在我的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,但它不起作用。
答案 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)
您应该深入研究承诺,因为它们是同步操作的方式。也许尝试将您的代码合并到函数中。