我对节点js上的异步很陌生。我在解析 xml 文件时使用瀑布方法,如下所示:
$('situation').each( function(){
var situation = [];
$(this).find('situationRecord').each( function(i){
var record = this;
async.waterfall([
function (callback){
var filter = {
startLocationCode: $(record).find('alertCMethod2SecondaryPointLocation').find('specificLocation').text(),
endLocationCode: $(record).find('alertCMethod2PrimaryPointLocation').find('specificLocation').text(),
overallStartTime: $(record).find('overallStartTime').text(),
overallEndTime: $(record).find('overallEndTime').text()
}
callback(null, filter, record);
},
function (filter, record, callback){
var timestamp = new Date().toDateInputValue();
var startDbResponse = 0;
var endDbResponse = 0;
if((filter.startLocationCode != '') && new Date(timestamp) >= new Date(filter.overallStartTime) && new Date(timestamp) <= new Date(filter.overallEndTime) ){
startDbResponse = locationCodeToGeodataRequst.geodataByLocationcode(filter.startLocationCode);
endDbResponse = locationCodeToGeodataRequst.geodataByLocationcode(filter.endLocationCode);
}
console.log("startDbResponse: ", startDbResponse);
console.log("endDbResponse: ", endDbResponse);
callback(null, filter, record, startDbResponse, endDbResponse);
},
function (filter, record, startDbResponse, endDbResponse, callback){
console.log("startDbResponse: ", startDbResponse);
console.log("endDbResponse: ", endDbResponse);
var situationRecord = createSituationRecord($, record, filter.startLocationCode, filter.endLocationCode, startDbResponse, endDbResponse);
console.log(situationRecord);
},
function (situationRecord, callback){
situation[i] = { situationRecord };
}
],
function(err, results){
console.error("There was an error by filtering the xml file");
console.error(err);
});
})
if(situation.length > 0){ //if situation is not empty
locations.push(situation);
}
})
console.log(locations);
}
在瀑布的这一部分,我向我的数据库发出请求,locationCodeToGeodataRequst.geodataByLocationcode(filter.startLocationCode);
但startDbResponse
和endDbResponse
undefined
:
....
function (filter, record, callback){
var timestamp = new Date().toDateInputValue();
var startDbResponse = 0;
var endDbResponse = 0;
if((filter.startLocationCode != '') && new Date(timestamp) >= new Date(filter.overallStartTime) && new Date(timestamp) <= new Date(filter.overallEndTime) ){
startDbResponse = locationCodeToGeodataRequst.geodataByLocationcode(filter.startLocationCode);
endDbResponse = locationCodeToGeodataRequst.geodataByLocationcode(filter.endLocationCode);
}
console.log("startDbResponse: ", startDbResponse);
console.log("endDbResponse: ", endDbResponse);
callback(null, filter, record, startDbResponse, endDbResponse);
},
....
它自己的请求之所以有效,是因为请求模块中的控制台.log显示正确的数据。所以我不明白为什么它没有定义。
这是请求模块:
exports.geodataByLocationcode = function geodataByLocationcode(locationcode){
let sql = "SELECT * FROM tmc WHERE LOCATION_CODE = " + locationcode;
let query = db.query(sql, (err, result) =>{
if(err == null){
//console.log(result);
return result;
}else{
console.log("Error by getting item from db: " + err);
throw err;
}
});
}
这是控制台的截图.log:
....
startDbResponse: undefined
endDbResponse: undefined
startDbResponse: undefined
endDbResponse: undefined
startDbResponse: 0
endDbResponse: 0
startDbResponse: 0
endDbResponse: 0
[]
//here comes the output of the requests as json objects
....
将
控制台日志移动到异步的最后一个函数。正如Manjeet指出的那样,异步需要时间,控制台打印很早。
function (situationRecord, callback){
situation[i] = { situationRecord };
if(situation.length > 0){ //if situation is not empty
locations.push(situation);
}
})
console.log(locations);
}
}