You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript项目获取评论及嵌套回复时replyId为空对象如何修复

问题根因

  1. getReply为异步函数,返回的是Promise对象,原代码直接将该Promise赋值给CommentDto的replyId字段,JSON序列化无法处理Promise类型,会直接转换为空对象{}
  2. 原接口返回时未等待所有嵌套的异步查询逻辑执行完成,导致响应返回时回复数据还未加载完毕。

修复方案

调整所有涉及嵌套查询的方法为异步等待逻辑,确保返回前所有层级的回复数据都已加载完成,修改后代码如下:

1. 调整查询主接口

@Get('/:entityId/comments')
async getAll(@Param('entityId') entityId: string): Promise<any> {
  const comments = await this.commentRepository.find({
    where: { entityId: entityId, replyId: null },
    order: { id: 'DESC' },
  });
  // 等待所有顶层评论的异步映射处理完成
  return Promise.all(comments.map(entity => this.mapper(entity)));
}

2. 调整回复查询方法

private async getReply(commentId: string) {
  const replies = await this.commentRepository.find({ where: { replyId: commentId } });
  console.log(replies);
  // 每个回复也需要执行映射逻辑,递归加载下一层回复
  return Promise.all(replies.map(entity => this.mapper(entity)));
}

3. 调整实体转Dto方法

private async mapper(entity: Comment): Promise<CommentDto> {
  // 等待当前评论的回复查询完成
  const replies = await this.getReply(entity.id);
  return new CommentDto(
    entity.id,
    entity.content,
    entity.authorId,
    entity.entityId,
    entity.creatAt,
    replies,
    entity.type,
  );
}

优化建议

上述递归查询的方案在评论量较大时会产生N+1查询问题,性能较差,可优化为:

  • 一次性查询当前entityId下的所有评论,再在内存中拼装成嵌套树形结构
  • 用数据库递归CTE语法一次性查询所有层级的关联评论
  • 直接使用TypeORM内置的树形实体(Tree Entity)能力处理嵌套评论场景

内容的提问来源于stack exchange,提问作者Марк

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 02:06:03