等待forEach完成,然后从我的诺言/函数返回 [英] Waiting for a forEach to finish before return from my promise / function

查看:67
本文介绍了等待forEach完成,然后从我的诺言/函数返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Firebase Cloud Firestore, however, I think this may be more of a JavaScript asynchronous vs synchronous promise return issue.

我正在执行查询以从一个集合中获取ID,然后遍历该查询的结果以基于该ID从另一集合中查找单个记录.

I am doing a query to get IDs from one collection, then I am looping over the results of that query to lookup individual records from another collection based on that ID.

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

Then I want to store each found record into an array and then return the entire array.

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

results.length is always 0 because return results fires before the forEach completes. If I print results.length from inside the forEach it has data.

在从外部promise和外部函数本身返回之前,如何等待forEach完成?

How can I wait until the forEach is done before returning from the outer promise and the outer function itself?

         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);
            });
          }

推荐答案

此处的窍门是用承诺而不是结果填充results.然后,您可以在该Promise数组上调用Promise.all()并获得所需的结果.当然,您不能在兑现承诺之前检查doc.exists是否已完成,因此一旦Promise.all()解决后,您将需要处理该问题.例如:

The trick here is to populate results with promises rather than the result. You can then call Promise.all() on that array of promises and get the results you want. Of course, you can't check if doc.exists before pushing the promise so you will need to deal with that once Promise.all() resolves. For example:

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
}

这篇关于等待forEach完成,然后从我的诺言/函数返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆