简体   繁体   English

节点承诺循环等待结果

[英]node promise for loop wait for result

How can I wait for the for loop to go to next loop? 如何等待for循环进入下一个循环?

How can I make sure that the userdetails is executed and realresult.playername is assigned to the new variable before passing it on ? 在传递新变量之前,如何确保执行userdetails并将realresult.playername分配给新变量?

code: 码:

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

You're trying to write a promise that, when it resolves, returns the array of resolved promise values. 您正在尝试编写一个承诺,该承诺在解析时将返回已解析的承诺值数组。 There are 2 things you should do here: 您应该在这里做两件事:

  1. Use return to await the completion of a promise. 使用return来等待诺言的完成。 In a promise chain, nothing actually resolves the promise value unless it is return ed. 在promise链中,除非将promise值return否则什么都无法解决。 (You should also use this for message.find() since it's also giving you a promise.) (您还应该将其用于message.find()因为它也可以给您带来希望。)
  2. Construct the array as an array of promises, rather than iterating and having the promises push into the array when they resolve. 将数组构造为一个Promise数组,而不是迭代并在它们解决时让Promise推入数组。
  3. Use Promise.all() to collect the promise objects - all() returns only after all of the promises passed to it have resolved. 使用Promise.all()收集的承诺对象- all()返回只毕竟传递给它的承诺已经解决。
  4. (optional) Don't reuse the result variable name to mean multiple things. (可选)不要重复使用result变量名称来表示多种含义。 It's not wrong here, but it can cause unnecessary confusion. 这里没有错,但是会引起不必要的混乱。

Put together, this would look something like: 放在一起,这看起来像:

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

so I thought it is a good idea trying solving it with the combination of generators and promises, I'm not sure that its the best way to go, but Its a good practice for the combination of the two so I gave it a try. 因此,我认为尝试通过生成器和Promise的组合来解决它是一个好主意,我不确定这是最好的方法,但是将两者结合起来是一个好习惯,所以我尝试了一下。

The idea is that the generator function is waiting for the callback function before starting a new iteration and the callback function is waiting for both promises to complete before telling the generator function to go on iterating. 这个想法是生成器函数在开始新的迭代之前正在等待回调函数,并且回调函数在告诉生成器函数继续进行迭代之前正在等待两个承诺完成。

here is a more simple example that I first tried on codepen 这是我首先在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