在javascript中按顺序执行promises

时间:2017-01-24 02:51:15

标签: javascript mongodb promise sequential

我一直在尝试使用承诺通过找到在最短时间内工作的人来实现让人们轮班。为此,我使用聚合将每个人的可用性文档与包含他们上次工作的记录文档相关联。它似乎正在跳过与promises有关的整个代码段,因为它将selectedPeopleList打印为空数组。这是我的代码:

var selectedPeopleList = [];

var sequentially = function(shifts) {

var p = Promise.resolve();

shifts.forEach(function (){
   p=p.then( function() { return collection.aggregate([
       {
          $lookup: 
            {
              from: "personRecord",
              localField: "ATTU_ID",
              foreignField: "ATTU_ID",
              as: "record"
            } 
        },

        {
          $match : { 'Available[]' : { $elemMatch : { $eq : shift.value } }, "record.ATTU_ID": { $nin : _.map(selectedPeopleList, 'ATTU_ID') } }
        },

        { 
          $sort : { "record.lastShift" : 1 }
        }
          ]).toArray(function(err, docs){ 
            assert.equal(err, null);

          }).then(function (result) {
            if(docs && docs.length) {
              selectedPeopleList.push({ ATTU_ID : docs[0].ATTU_ID, Name: docs[0].Name });
              console.log(docs[0]);
            }
          });
        });            
  })
  return p;
};
console.log(selectedPeopleList);

2 个答案:

答案 0 :(得分:2)

Promise不会使异步代码同步

将最后一行更改为

p.then(function() {
    console.log(selectedPeopleList);
});

另外,你不需要在forEach中返回任何内容,因为根本没有使用返回值

答案 1 :(得分:0)

您的代码中存在相当多的小错误。

确保正确遵循异步代码流程。我试图解决我的代码段中的所有问题。



var selectedPeopleList = [];

var sequentially = function(shifts) {

var p = Promise.resolve();
//use promise all to merge all promises in to 1. and use map to return the promises.
Promise.all(shifts.map(function (){
   p=p.then( function() { return collection.aggregate([
       {
          $lookup: 
            {
              from: "personRecord",
              localField: "ATTU_ID",
              foreignField: "ATTU_ID",
              as: "record"
            } 
        },

        {
          $match : { 'Available[]' : { $elemMatch : { $eq : shift.value } }, "record.ATTU_ID": { $nin : _.map(selectedPeopleList, 'ATTU_ID') } }
        },

        { 
          $sort : { "record.lastShift" : 1 }
        }
          ]).toArray(function(err, docs){ 
            assert.equal(err, null);
          })
   })//make sure you finish then! before you start a new one.
   
   .then(function (result) {
            console.log('our results', result);
            if(result && result.length) { //use result variable!
              selectedPeopleList.push({ ATTU_ID : result[0].ATTU_ID, Name: result[0].Name });
              
            }
         
        });            
  })

  return p;
})
)
.then(function(){ //lets await all the promises first. and then read the list.
  
  console.log(selectedPeopleList);
  });