簡體   English   中英

節點承諾循環等待結果

[英]node promise for loop wait for result

如何等待for循環進入下一個循環?

在傳遞新變量之前,如何確保執行userdetails並將realresult.playername分配給新變量?

碼:

return new Promise( function (resolve, reject) {

    arr = [];


    messages.find({convid: convid}).then(function(result) {

        for(var a in result) {
            realresult = result[a];

            userData.userDetails(realresult.userid).then(function (result) {
                realresult.playername = result.username;
            });
            userData.usercashinfo(realresult.userid).then(function (resulttwo) {
                realresult.playerdetails = resulttwo;
            });

            arr.push(realresult);

        }

        return resolve(arr);
    });
});

您正在嘗試編寫一個承諾,該承諾在解析時將返回已解析的承諾值數組。 您應該在這里做兩件事:

  1. 使用return來等待諾言的完成。 在promise鏈中,除非將promise值return否則什么都無法解決。 (您還應該將其用於message.find()因為它也可以給您帶來希望。)
  2. 將數組構造為一個Promise數組,而不是迭代並在它們解決時讓Promise推入數組。
  3. 使用Promise.all()收集的承諾對象- all()返回只畢竟傳遞給它的承諾已經解決。
  4. (可選)不要重復使用result變量名稱來表示多種含義。 這里沒有錯,但是會引起不必要的混亂。

放在一起,這看起來像:

return messages.find(...).then(function(result) {
  var promiseArr = [];
  for (var a in result) {
    promiseArr.push(
      promise.all([userData.userDetails(...), userData.usercashinfo(...)])
      .then(function(detailinfo) {
        var realresult = result[a];
        var details = detailinfo[0];
        var cashinfo = detailinfo[1];
        realresult.playername = details.username;
        realresult.playerdetails = cashinfo;
        return realresult;
    });
  }
  return Promise.all(promiseArr);
});

因此,我認為嘗試通過生成器和Promise的組合來解決它是一個好主意,我不確定這是最好的方法,但是將兩者結合起來是一個好習慣,所以我嘗試了一下。

這個想法是生成器函數在開始新的迭代之前正在等待回調函數,並且回調函數在告訴生成器函數繼續進行迭代之前正在等待兩個承諾完成。

這是我首先在Codepen上嘗試過的更簡單的示例

return new Promise( function (resolve, reject) {
    arr = [];
    messages.find({convid: convid}).then(function(result) {
        function* iterations() {
            for (var i = 0; i < result.length; i++) {
                realresult = result[i];
                try {
                    var cbResult = yield cb(result[i].userid);
                    realresult.playername = cbResult.playername;
                    realresult.playerdetails = cbResult.playerdetails;
                    arr.push(realresult);
                } catch (e) { reject(e) }
            }
            return arr.value;
        }

        var it = iterations();
        it.next();

        function cb(userid) {
            Promise.all([
                       userData.userDetails(userid),
                       userData.usercashinfo(userid)
                       ]).then(
                           function(values) {
                               var realresult = {playername : values[0], playerdetails : values[1]}
                               returnValue = it.next(realresult);
                               if (returnValue.done) {
                                   resolve(returnValue);
                               }
                           },
                           function(e) { reject(e) }
                       );
        }
    });
});

暫無
暫無

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

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