【问题标题】:Fulfilling promises sequentially in javascript [duplicate]在javascript中按顺序履行承诺[重复]
【发布时间】:2017-01-24 11:24:13
【问题描述】:

我一直在尝试通过寻找工作时间最短的人来使用承诺来履行轮班工作。为此,我使用聚合将每个人的可用性文档与包含他们上次工作时间的记录文档链接起来。似乎它跳过了与承诺有关的整个代码部分,因为它将 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);

【问题讨论】:

  • Promise 不会使异步代码同步

标签: javascript mongodb promise sequential


【解决方案1】:

Promise 不会使异步代码同步

把最后一行改成

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

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

【讨论】:

    【解决方案2】:

    您的代码中有不少小错误。

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

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

    【讨论】:

    • 我做了你建议的编辑;但是,现在 selectedPeopleList 数组没有打印。实际上没有任何东西打印到控制台。
    • 对不起,我仍然对docs 有一些错误的引用(应该是result)你能跑一下看看它现在返回什么吗?
    • 我也试过了,但仍然没有打印出任何东西。甚至没有 console.log("our results", result);
    • 我需要知道您遇到了什么错误。可能是您的集合函数错误或 toArray 错误。由于我无法测试它,您必须自己做。简单的原理你要知道,第一个then返回的是后面then()回调中的第一个参数。这些 then/promise 之外的代码在 promise 内部的代码之前执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 2021-01-09
    • 2014-06-04
    • 2017-11-09
    • 2017-07-14
    相关资源
    最近更新 更多