当前位置: 首页 > 知识库问答 >
问题:

在我的诺言/功能回来之前等待一个forEach完成

羊光辉
2023-03-14

我使用的是Firebase Cloud Firestore,然而,我认为这可能更像是JavaScript异步与同步promise返回的问题。

我正在执行一个查询以从一个集合中获取ID,然后循环该查询的结果以根据该ID从另一个集合中查找单个记录。

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

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

共有1个答案

贺飞
2023-03-14

这里的诀窍是用promise而不是结果填充结果。然后可以对该promise数组调用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
}
 类似资料:
  • 问题内容: 我有以下 我有一个运行一些ajax的函数,然后根据ajax是否成功返回true或false。我从代码的多个位置调用了这个ajax函数。 因为该函数在ajax完成之前结束,所以它总是返回false。如何避免这种情况? 我读到一些建议我在函数中执行的操作,然后将和函数移至我的和函数。但是,在我的方法中,我进行了大量的计算。很多代码。因此,问题在于,如果我将功能移至其他功能,那么我将复制一堆

  • 我仍在为承诺而挣扎,但多亏了这里的社区,我取得了一些进步。 我有一个简单的JS函数,它查询解析数据库。它应该返回结果数组,但显然由于查询的异步性质(因此有承诺),函数在结果之前返回,给我留下一个未定义的数组。 我需要做什么才能让这个函数等待承诺的结果呢? 这是我的代码:

  • 问题内容: 我有一个简单的功能,可以从Firebase加载数据。 当前,即使有要加载的数据,此函数也会始终返回。之所以这样做,是因为它永远不会执行执行完成块,在函数返回之前,它不会在数组中加载数组。我正在寻找一种使函数仅在调用完成块后才返回的方法,但不能将return放在完成块中。 问题答案: (关于此问题的变化经常出现在SO上。我永远找不到一个好的,全面的答案,因此下面尝试提供这样的答案) 你不

  • 问题内容: 我读到用关键字标记的异步函数隐式返回一个promise: 但这不连贯…假设返回一个诺言,而await关键字将从诺言中返回值,而不是诺言itsef,那么我的getVal函数 应该 返回该值,而不是隐式诺言。 那到底是什么情况?用async关键字标记的函数是隐式返回promise还是控制它们返回的内容? 也许,如果我们不明确地返回某些东西,那么他们会隐式地返回一个诺言…? 更清楚地说,上述

  • 我要做的是异步计算树结构的深度,我将有树的第一层,我想启动一个异步线程来分别计算每个节点的深度。 在计算过程中,树中显然可能有一个分叉,在这一点上,我想踢一个额外的线程来计算那个分支。 我已经得到了这个工作,但我需要做一些整理逻辑,当所有这些未来完成。但我对这一过程中产生的额外的可完成的未来感到困扰。 我会用什么方法来保存所有开始的CompletableFutures+那些动态创建的,并且在执行任