TypeScript项目获取评论及嵌套回复时replyId为空对象如何修复
问题根因
getReply为异步函数,返回的是Promise对象,原代码直接将该Promise赋值给CommentDto的replyId字段,JSON序列化无法处理Promise类型,会直接转换为空对象{}- 原接口返回时未等待所有嵌套的异步查询逻辑执行完成,导致响应返回时回复数据还未加载完毕。
修复方案
调整所有涉及嵌套查询的方法为异步等待逻辑,确保返回前所有层级的回复数据都已加载完成,修改后代码如下:
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,提问作者Марк
相关产品推荐
相关产品推荐

