在使用Promise.all开始另一个mongoose请求之前完成一组mongoose请求

时间:2017-07-13 11:58:47

标签: javascript node.js mongodb mongoose promise

我使用forEach循环创建两个promises数组。我需要第一个请求在第二个开始之前完全完成。但是,当我检查我的日志时,我看到"第一个"和"第二"消息没有以正确的顺序出现,即使我认为我已经配置了承诺,以便他们愿意。帮我弄清楚我做错了什么?

感谢。

function saveInstance(){
    return new Promise((resolve,reject)=>{
        var saveInstances = [];
        dateStarts.forEach(dateStart=>{
            var trimmedDate = siteBody.substr(dateStart+dateNeedle.length, 400).trim();
            var trimmedDateArray = trimmedDate.split(',');
            var instanceId = trimmedDateArray[0].substr(7,6);
            titleRecords.findOne({"titleByDate.instanceId": instanceId}, function(err,data){
                if (err) throw err;
                if (!data & trimmedDateTime !=null){
                    var instancerecord = new titleRecords();
                    instancerecord.titleByDate.instanceId      = instanceId;
                    instancerecord.newTitle                    = 1;
                    saveInstances.push(instancerecord.save(function(err,data){
                    console.log('This should print first');
                    err ? reject(): resolve();
                }));
                }               
            })
        })  
    Promise.all(saveInstances).then(updateInstanceTime,reject); 
    })
}

function updateInstanceTime(){
    return new Promise((resolve,reject)=>{
        var updateInstanceTimes = [];
        dateStarts.forEach(dateStart=>{
            var trimmedDate = siteBody.substr(dateStart+dateNeedle.length, 400).trim();
            var trimmedDateArray = trimmedDate.split(',');
            var titleTitle = trimmedDateArray[1].substr(2, trimmedDateArray[1].trim().length-2);
            var instanceId = trimmedDateArray[0].substr(7,6);

            var conditions      = {'titleByDate.instanceId'  : instanceId};
            var update          = {'titleByDate.lastSeen': localISOTime };
            updateInstanceTimes.push(titleRecords.update(conditions, update,function(err,data){
                console.log('This should print second');
                (err) ? reject() : resolve();
            }));
        })
    Promise.all(updateInstanceTimes).then(resolve,reject);  
    })
}

saveInstance();

1 个答案:

答案 0 :(得分:0)

你的代码很难推理,因为你在混合节点回调和承诺。如果你使用promises坚持它。

  1. 通常您不需要手动创建承诺。众所周知,#34;被遗忘的承诺" anti-pattern
  2. 使用promisified版本的方法不要将回调与Promises混合。
  3. !data & trimmedDateTime !=null& - 是按位和运算符。我相信你想要&&
  4. 不要使用forEach创建另一个包含已转换项目的数组。对此有map
  5. 以下是如何重写第一个函数的示例。你应该为第二个做同样的事情。

    function saveInstance() {
      return Promise.all(
        dateStarts.map(dateStart => {
          var trimmedDate = siteBody.substr(dateStart + dateNeedle.length, 400).trim();
          var trimmedDateArray = trimmedDate.split(',');
          var instanceId = trimmedDateArray[0].substr(7, 6);
    
          return titleRecords.findOne({
              "titleByDate.instanceId": instanceId
            })
            .exec()
            .then(data => {
              if (!data) {
                var instancerecord = new titleRecords();
                instancerecord.titleByDate.instanceId = instanceId;
                instancerecord.newTitle = 1;
    
                return instancerecord.save()
              }
              return data
            })
        })
      ).then(updateInstanceTime)
    }