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

Ada*_*amG 7 javascript node.js firebase google-cloud-firestore

我正在使用Firebase Cloud Firestore,但是,我认为这可能更像是JavaScript异步vs同步承诺返回问题.

我正在进行查询以从一个集合中获取ID,然后我循环查询该查询的结果,以根据该ID查找来自另一个集合的各个记录.

然后我想将每个找到的记录存储到一个数组中,然后返回整个数组.

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

在从外部promise和外部函数本身返回之前,我怎么能等到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);
            });
          }
Run Code Online (Sandbox Code Playgroud)

Mar*_*yer 7

这里的诀窍是填充results承诺而不是结果.然后Promise.all(),您可以调用该数组的promise并获得所需的结果.当然,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
}
Run Code Online (Sandbox Code Playgroud)