在从我的承诺/function返回之前等待forEach完成

我正在使用Firebase Cloud Firestore,但是,我认为这可能是更多的JavaScriptasynchronous与同步承诺返回问题。

我正在做一个查询来从一个集合中获取ID,然后循环查询的结果从另一个集合中查找基于该ID的单个logging。

然后我想将每个find的logging存储到一个数组中,然后返回整个数组。

results.length始终为0,因为return results在forEach完成之前触发。 如果我从forEach内部打印results.length它有数据。

我怎么才能等到forEach完成之后才从外部承诺和外部函数本身返回呢?

  getFacultyFavoritesFirebase() { var dbRef = db.collection("users").doc(global.user_id).collection("favorites"); var dbQuery = dbRef.where("type", "==", "faculty"); var dbPromise = dbQuery.get(); var results = []; return dbPromise.then(function(querySnapshot) { querySnapshot.forEach(function(doc) { var docRef = db.collection("faculty").doc(doc.id); docRef.get().then(function(doc) { if (doc.exists) { results.push(doc); } }) }); console.log(results.length); return results; }) .catch(function(error) { console.log("Error getting documents: ", error); }); } 

这里的诀窍是用promise来填充results而不是结果。 然后你可以调用Promise.all()这个承诺数组并得到你想要的结果。 当然,在推送诺言之前,你不能检查doc.exists ,所以你需要处理一次Promise.all()解决。 例如:

 function getFacultyFavoritesFirebase() { var dbRef = db.collection("users").doc(global.user_id).collection("favorites"); var dbQuery = dbRef.where("type", "==", "faculty"); var dbPromise = dbQuery.get(); // return the main promise return dbPromise.then(function(querySnapshot) { var results = []; querySnapshot.forEach(function(doc) { var docRef = db.collection("faculty").doc(doc.id); // push promise from get into results results.push(docRef.get()) }); // dbPromise.then() resolves to a single promise that resolves // once all results have resolved return Promise.all(results) }) .catch(function(error) { console.log("Error getting documents: ", error); }); } getFacultyFavoritesFirebase .then(results => { // use results array here and check for .exists } 

如果同时有多个工作项目来自循环,则可以收集所有工作项目的所有承诺,并等待他们完成Promise.all() 。 可能的解决scheme的一般forms如下所示:

 const promises = [] // collect all promises here items.forEach(item => { const promise = item.doWork() promises.push(promise) }) Promise.all(promises).then(results => { // continue processing here // results[0] is the result of the first promise in the promises array }) 

你可以适应这个适合你自己特定forms的东西。