节点js同步每个循环

时间:2017-10-12 08:35:38

标签: javascript node.js foreach synchronization

在我的Node JS后端我运行此方法。

var locations = [];

exports.constructionsiteParser = function constructionsiteParser(response){
    var timestamp = new Date().toDateInputValue();
    const $ = cheerio.load(response);
    $('situation').each( function(){
    var situation = [];
        $(this).find('situationRecord').each( function(i){
          var startLocationCode = $(this).find('alertCMethod2SecondaryPointLocation').find('specificLocation').text();
      var endLocationCode = $(this).find('alertCMethod2PrimaryPointLocation').find('specificLocation').text();
      var overallStartTime = $(this).find('overallStartTime').text();
      var overallEndTime = $(this).find('overallEndTime').text();
      if((startLocationCode != '') && new Date(timestamp) >= new Date(overallStartTime) && new Date(timestamp) <= new Date(overallEndTime) ){
        Promise.all([
          locationCodeToGeodataRequst.geodataByLocationcode(startLocationCode), 
          locationCodeToGeodataRequst.geodataByLocationcode(endLocationCode) 
        ]).then( values =>{
          return createSituationRecord($, this, startLocationCode, endLocationCode, values[0], values[1]);
        }).then( function(obj){
          console.log("before push", situation);
          situation.push(obj);
          console.log("after push", situation);
          return situation;
        }, handleError);
      }
    })
    console.log("from outter", situation.length);
    if(situation.length > 0){ //if situation is not empty
      locations.push(situation);
    }
   })
        console.log(locations);
  }

底部的console.log("from outter", situation.length);始终为0 console.log(locations)也是空的

这是日志的一部分:

...
from outter 0
from outter 0
from outter 0
from outter 0
from outter 0
[]
before push []
after push [....

我认为这是因为节点服务器在内部每个循环结束之前运行底部。所以我想让它更加同步。我想做的是:

outer each{

  //run this first
  inner each{
  .....
  }

  //if inner each is done run this
  if(...){}

}

但我不知道如何使用正确的语法。 我已尝试使用嵌套的Promises,但它不起作用。

3 个答案:

答案 0 :(得分:2)

你可以归还这个承诺。在来电者处理

答案 1 :(得分:1)

您可以使用async.eachOf()。我采用了不同的方法使代码同步。希望它可以帮到你。

'use strict';


let locations = [];

exports.constructionsiteParser = function constructionsiteParser(response) {
  const $ = cheerio.load(response);

  $('situation').each(function () {
    let situation = [];

    async.eachOf($(this).find('situationRecord'), function (value, key, callback) {
      innerLoop(callback);
    }, function (err, situation) {
      if (err) {
        return console.error(err.message);
      }

      console.log("from outter", situation.length);

      // this will run only if the inner loops completes
      if (situation.length > 0) { //if situation is not empty
        locations.push(situation);
      }
    });


  });
  console.log(locations);
};

function innerLoop(callback) {
  let startLocationCode = $(this).find('alertCMethod2SecondaryPointLocation').find('specificLocation').text();
  let endLocationCode = $(this).find('alertCMethod2PrimaryPointLocation').find('specificLocation').text();
  let overallStartTime = $(this).find('overallStartTime').text();
  let overallEndTime = $(this).find('overallEndTime').text();

  if (isInvalid(startLocationCode, overallStartTime, overallEndTime)) {
    return callback('some error msg');
  }

  Promise.all([
    locationCodeToGeodataRequst.geodataByLocationcode(startLocationCode),
    locationCodeToGeodataRequst.geodataByLocationcode(endLocationCode)
  ]).then(values => {
    return createSituationRecord($, this, startLocationCode, endLocationCode, values[0], values[1]);
  }).then((obj) => {
    return callback(null, obj);
  }).catch((err) => {
    console.log('err', err.stack);
    return callback(err);
  });
}

function isInvalid(startLocationCode, startTime, endTime) {
  let timestamp = new Date().toDateInputValue();

  let isEmptyCode = startLocationCode === '';
  let isYetToStart = new Date(timestamp) < new Date(startTime);
  let isOver = new Date(timestamp) > new Date(endTime);

  return isEmptyCode || isYetToStart || isOver;
}

答案 2 :(得分:0)

您应该深入研究承诺,因为它们是同步操作的方式。也许尝试将您的代码合并到函数中。