簡體   English   中英

javascript承諾仍將同步執行代碼

[英]javascript promise still executing code synchronously

所以基本上我有一個Web應用程序,可從Firebase檢索數據。 由於從Firebase檢索數據需要花費大量時間,因此我使用了promise來使我的代碼在正確的時間填充。 這是我的代碼:

var promise = getDataFirebase();
promise.then(function () {
    console.log(Collect);

    console.log("firsst");
    return getDataFirebaseUser();
}).then(function () {

    console.log("Second");

});



function getDataFirebase() {
    return new Promise(function (resolve, reject) {
        refReview.on("value", function (snap) {
            var data = snap.val();
            for (var key in data) {


                Collect.push({
                    "RevieweeName": data[key].revieweeID.firstname.concat(" ", data[key].revieweeID.lastname),
                    "ReviewerName": data[key].reviewerID.firstname.concat(" ", data[key].reviewerID.lastname),
                    rating: data[key].rating,
                    content: data[key].content,
                    keyOfReviewee: data[key].revieweeID.userID
                })
                var getDataToUsers = firebase.database().ref("users").child(data[key].revieweeID.userID);
                getDataToUsers.once("value", async function (snap) {
                    var fnLn = snap.val();
                    var first = fnLn.isTerminated;
                    console.log("terminateStatus", first);

                });


            }//end of for loop
            resolve();
        }); //end of snap 
    });
}

因此在getDataFirebase函數中,數據是從firebase中檢索的,並被推送到名為Collect的數組中。 因此,在推送1行之后,它會再次向Firebase查詢另一個數據表,然后繼續循環。 這里的問題是,我想在解決諾言之前完成所有流程。

根據代碼,控制台的輸出如下:

 Collect (array)
first
Second
terminateStatus, 1

一定是

   Collect (array)
 first
terminateStatus,1
second

我不是100%不確定您的代碼如何工作,但看起來您在refReview.on("value")上做的正確:在調用Firebase之前創建一個promise,然后再解決它。 但是您沒有在getDataToUsers.once("value") 在那里,您正在觸發事件,而不是等待它返回-for循環繼續進行,所有回調都在以后處理,但是resolve是在for循環的末尾,所以到那時為時已晚。

我的猜測是,您認為async關鍵字將導致for循環等待該作業完成,但是實際上,此操作僅是使回調返回一個promise —被on函數忽略。

您有幾種選擇,但是最好的選擇是使用Promise.all ,它接受一個諾言數組並等待所有諾言得到解決-但是您可能應該使用Firebase的Promise API而不是將諾言附加到事件API上。 所以它看起來像:

refReview.once('value')
    .then(snap => Promise.all(snap.val().map(item =>
        firebase.database()
            .ref("users")
            .child(item.revieweeID.userID)
            .once('value')
            .then(snap => {
                console.log('terminated');
            ])
    })));

(除了添加了natch的實際功能外)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM