我在节点中使用异步模块瀑布方法进行sql查询。我如何使用回调将两组数据发送到下一个函数。与第一个将qryUpdateCheck和qryCheckDbl传递给下一个函数的函数一样。如何正确完成。
async.waterfall([
function (callback) {
var requestUpdateCheck = new sql.Request([config]);
requestUpdateCheck.query("Some qryUpdateCheck", function (err, qryUpdateCheck) {
console.log('qryUpdateCheck', qryUpdateCheck);
});
var requestCheckDbl = new sql.Request([config]);
requestCheckDbl.query("Some qryRequestCheckDbl", function (err, recordset) {
console.log('qryCheckDbl', qryCheckDbl);
});
callback(null, qryUpdateCheck, qryCheckDbl);
},
function (qryUpdateCheck, qryCheckDbl, callback) {
console.log('hi from second from qryUpdateCheck', qryUpdateCheck);
console.log('hi from second from qryCheckDbl', qryCheckDbl);
if ((qryUpdateCheck.length == 1) && (qryCheckDbl.length == 0)) {
var requestUpdateLocID = new sql.Request([config]);
requestUpdateLocID.query("Last qryUodateLocID", function (err, recordset) {
console.log('qryUpdateLocID', recordset);
callback(null, recordset);
});
} else if ((qryUpdateCheck.length == 0) && (qryCheckDbl.length == 0)) {
var requestUpdateLocID = new sql.Request([config]);
requestUpdateLocID.query("Insert qry", function (err, recordset) {
console.log('qryUpdateLocID', recordset);
callback(null, recordset);
});
}
}
], function (err, result) {
// result now equals 'done'
console.log('done', result);
});
答案 0 :(得分:1)
我发现async.auto更适合这种情况。您将一个带有一组函数的对象传递给它,对于每个函数,您可以将其他函数名称作为依赖项传递。然后,它将同时运行它可以并行运行的任务,同时确保具有依赖关系的函数等待,直到它们在被调用之前都满意为止。它有点像魔术。
var request = new sql.Request([config]);
async.auto({
// this runs in parallel because it has no dependencies
requestUpdateCheck: function(callback) {
request.query("Some qryUpdateCheck", callback);
},
// this also runs in parallel because it has no dependencies
requestCheckDbl: function(callback) {
request.query("Some qryRequestCheckDbl", callback);
},
// this waits for the first two functions and then executes
requestUpdateLocID: ['requestUpdateCheck', 'requestCheckDbl', function(results, callback) {
console.log('Results from requestUpdateCheck and requestCheckDbl', JSON.stringify(results, null, 2));
var qryUpdateCheck = results.requestUpdateCheck;
var qryCheckDbl = results.requestCheckDbl;
if ((qryUpdateCheck.length == 1) && (qryCheckDbl.length == 0)) {
request.query("Last qryUodateLocID", function (err, recordset) {
console.log('qryUpdateLocID', recordset);
callback(err, recordset);
});
} else if ((qryUpdateCheck.length == 0) && (qryCheckDbl.length == 0)) {
request.query("Insert qry", function (err, recordset) {
console.log('qryUpdateLocID', recordset);
callback(err, recordset);
});
}
}]
}, function(err, results) {
console.log('done:', err || results);
});
results
将包含所有已完成函数的数据。
这是一个非常简单的示例案例,有些人可能认为promises.all更适合。就个人而言,当事情变得更复杂时,我发现async.auto
确实有帮助。因此,为了保持一致性,我将它用于大多数异步控制流,并发现它可以处理大多数情况。
答案 1 :(得分:0)
您可以执行嵌套并行调用。这是使用setTimeout
的伪示例:
async.waterfall([
function(callback) {
async.parallel({
requestUpdateCheck: function(callback) {
setTimeout(function() {
callback(null, 'UpdateCheck')
}, 500)
},
requestCheckDbl: function(callback) {
setTimeout(function() {
callback(null, 'CheckDbl')
}, 500)
}
}, function(err, result) {
// here the parallel op is done
callback(err, result);
})
},
function(result, callback) {
console.log('hi from second from qryUpdateCheck', result.qryUpdateCheck);
console.log('hi from second from qryCheckDbl', result.qryCheckDbl);
callback(null, result);
}
], function(err, result) {
// result now equals 'done'
console.log('done', result);
});