Promise.all未执行问题求助:异步流程异常及代码排查
问题分析与解决方案
我来帮你拆解下当前遇到的两个核心问题,再给出对应的修复方案:
问题1:Promise.all内部回调从未执行
你通过Firestore get()方法获取的result2是QuerySnapshot对象,它本身不是数组,并没有map方法。要遍历查询到的文档,必须访问它的docs属性——这才是存储所有文档实例的数组。这就是为什么你回调里的alert(doc2)完全没触发的原因:result2.map(...)根本没有执行逻辑,Promise.all接收的是空数组,直接就resolve了。
问题2:forEach遍历会导致insertData提前执行
forEach方法不会等待异步回调完成,它会同步遍历所有元素并立即触发每个异步函数,然后直接执行后续的insertData,这就导致newRec还没被正确处理就传入了函数。
修正后的代码
这里我修复了map的调用对象,同时优化了数组处理逻辑(避免splice导致的索引错位问题),确保所有异步操作完成后才调用insertData:
let userRef2 = firebase.firestore().collection("users").doc(participantID); const result2 = await firebase.firestore().collection("recommendedVideo").where("user", "==", userRef2).get(); alert("3 "+result2.size); try { await Promise.all(result2.docs.map(async doc2 => { alert(doc2); // 获取视频引用ID const videoRef = doc2.data().video.id; alert("videoRef "+videoRef); const doc3 = await firebase.firestore().collection("videos").doc(videoRef).get(); if (!doc3.exists) { alert("Não existe doc videos"); return; } const sequence = doc3.data().sequenceNumberID; // 用filter创建新数组,避免splice导致的索引错位问题 newRec = newRec.filter(item => String(sequence) !== String(item)); })); } catch (error) { alert(error); } // 所有异步操作完成后再执行insertData insertData(newRec);
额外优化说明
- 替换
splice为filter:原来的循环+splice会导致数组索引错位(删除元素后后续元素前移,循环会跳过部分元素),用filter创建新数组的方式更安全、简洁。 - 使用
try/catch包裹异步逻辑:和你原来的.catch效果一致,但更贴合async/await的代码风格。
内容的提问来源于stack exchange,提问作者Ricardo Caldas
相关产品推荐
相关产品推荐

