簡體   English   中英

For異步功能中的循環和計時問題

[英]For loop in async function and timing issue

我正在查詢mongodb中通過會話傳遞的用戶電子郵件。 找到該電子郵件后,它將尋找該用戶的朋友,並且這些朋友應該傳遞給usersFriends數組,然后將其以塊的形式發送給瀏覽器。 我將所有代碼都包含在此塊中,即使事務塊並不是真的相關,所以我認為。

問題是:除非console.logfor循環內,否則usersFriends數組將在usersFriends輸出一個空數組。 有什么想法嗎?

app.get('/api/chunk', function(req, res){

var last5;
var usersFriends = [];

Transaction.find().sort({$natural:-1}).limit(5).exec(function(err, docs){
    if (err) {
        console.log(err);
    } else {
        last5 = docs;           
    }
});

User.findOne({ email: req.user.email }, function(err, user){
    if (!user) {
        console.log(err);
    } else {
        for (var i = 0; i < user.friends.length; i++) {
            (function(cntr){
            User.findOne({ email: user.friends[cntr].email}, function(err, result) {
                result.password = "Sneaky sneaky"
                var name = result.firstName + " " + result.lastName;                    
                usersFriends.push({
                    name: name,
                    index: cntr
                });
            });                 
            })(i);

            var chunk = {
                "friends": usersFriends,
                "transactions": last5
            };
        }       }console.log(usersFriends); // empty array 
});

});

結合我們在注釋中討論的所有各種變化,以獲取此更改列表:

  1. 在IIFE中傳遞cntr,以便為每個單獨的.findOne()請求唯一捕獲該.findOne()
  2. 在每個響應中,檢查這是否是最后一個響應,因此我們知道所有結果都已到達。
  3. Transaction.find()操作的完成開始啟動.findOne()操作(由於我不知道該操作,因此我猜測應該如何實現此特定方面,但是您應該能夠看到一般的想法)。

雖然會導致以下代碼:

app.get('/api/chunk', function(req, res) {

    var last5;
    var usersFriends = [];

    Transaction.find().sort({
        $natural: -1
    }).limit(5).exec(function(err, docs) {
        if (err) {
            console.log(err);
        } else {
            last5 = docs;
            User.findOne({
                email: req.user.email
            }, function(err, user) {
                if (!user) {
                    console.log(err);
                } else {
                    var totalCnt = user.friends.length;
                    for (var i = 0; i < totalCnt; i++) {
                        (function(cntr) {
                            User.findOne({
                                email: user.friends[cntr].email
                            }, function(err, result) {
                                result.password = "Sneaky sneaky"
                                var name = result.firstName + " " + result.lastName;
                                usersFriends.push({
                                    name: name,
                                    index: cntr
                                });
                                if (usersFriends.length === totalCnt) {
                                    // all results are done here
                                    // you can create the final response
                                    var chunk = {
                                        "friends": usersFriends,
                                        "transactions": last5
                                    };
                                }
                            });
                        })(i);

                    }
                }
            });
        }
    });
});     

暫無
暫無

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

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