嵌套Promise解析异常:返回Recipe数组为空问题排查
嵌套Promise未正确解析导致返回空数组的问题解决
你的核心问题出在forEach循环无法正确等待异步操作完成——不管是最初的嵌套then写法,还是后来重构的async/await版本,forEach都不会等待内部的异步任务执行完毕就会继续后续代码,导致返回recipes数组时,异步请求还没完成,数组自然是空的。
问题根源拆解
在你重构后的getAllRecipesByUserId中,userRecipes.forEach(async (recipeId) => {...})这段代码存在逻辑漏洞:forEach会立刻遍历所有元素、触发每个异步函数,但它本身不会等待这些异步函数执行完成。当代码走到return recipes时,所有getDocs请求还在后台运行,数组根本没被填充。
正确实现方式
把forEach换成map,将每个异步操作转换成Promise,再用Promise.all等待所有Promise完成后统一收集结果:
async getAllRecipesByUserId(): Promise<Recipe[]> { const userRecipes = await this.userService.userRecipeIds(); // 用map生成所有异步请求的Promise数组 const recipePromises = userRecipes.map(async (recipeId) => { const q = query(this.recipeCollection, where('id', '==', recipeId)); const querySnapshot = await getDocs(q); // 根据id查询只会返回一个匹配文档,直接取第一个即可 return querySnapshot.docs[0].data() as Recipe; }); // 等待所有异步请求完成,返回完整的Recipe数组 return Promise.all(recipePromises); }
同时你的ngOnInit也可以改成async/await写法,代码更简洁直观:
async ngOnInit(): void { this.allRecipes = await this.recipeService.getAllRecipesByUserId(); this.recipe = this.allRecipes[0]; console.log(this.recipe); }
额外性能优化
如果你的数据库支持in操作符批量查询,还能进一步减少请求次数,避免循环发起单个查询:
async getAllRecipesByUserId(): Promise<Recipe[]> { const userRecipes = await this.userService.userRecipeIds(); if(userRecipes.length === 0) return []; // 用in操作符批量查询所有目标id const q = query(this.recipeCollection, where('id', 'in', userRecipes)); const querySnapshot = await getDocs(q); return querySnapshot.docs.map(doc => doc.data() as Recipe); }
这样只需要一次getDocs请求,既提升性能,也从根源上避免了异步循环的问题。
内容的提问来源于stack exchange,提问作者Damien Garlinge
相关产品推荐
相关产品推荐

