简体   繁体   中英

node promise for loop wait for result

How can I wait for the for loop to go to next loop?

How can I make sure that the userdetails is executed and realresult.playername is assigned to the new variable before passing it on ?

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. In a promise chain, nothing actually resolves the promise value unless it is return ed. (You should also use this for message.find() since it's also giving you a promise.)
  2. Construct the array as an array of promises, rather than iterating and having the promises push into the array when they resolve.
  3. Use Promise.all() to collect the promise objects - all() returns only after all of the promises passed to it have resolved.
  4. (optional) Don't reuse the result variable name to mean multiple things. 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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM