我是Nodejs的新手,需要一些指导来编写更好的代码。这是我的问题。
我有一个函数,这是我使用异步瀑布模型。我想在循环中调用那个函数,如果在中间出了问题就中断循环,或者在for循环结束时通知一些结果。但是由于某种原因,我得到了一个未定义的响应。
function myFunc (arg1) {
async.waterfall(
[
function() {
//do something
callback(null, data);
},
function(data, callback) {
//do something
callback(null, 'done');
}
],
function(err, result) {
return {"error" : err, "res" : result};
}
}
//Here I am calling my function
for (var d in mydata) {
var retdata = myFunc (mydata[d]); //retdata has undefined in it as this line executes before the last function of water fall
if (retdata.error !== 200) {
return // break loop
}
}
//Other wise if every thing is fine nofify after the for loop end
console.log ("done");
简而言之,当瀑布的最后一个函数出错时,在结束或中断循环时通知结果(如果为true)的正确和最好的方法是什么?
您不能使用同步方法(如for循环)并期望您的代码等待直到异步任务完成。你不能使用return从异步函数中获取数据。
这是一种使用async.map
重构代码的方法。注意回调结构。还要确保您引用的是async文档。
//Async's methods take arrays:
var mydata = {a: 'foo', b: 'bar'};
var myarr;
for (var d in mydata) {
myarr.push(mydata[d]);
// Beware, you might get unwanted Object properties
// see e.g. http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript/3010848#3010848
}
async.map(myarr, iterator, mapCallback);
function iterator(d, done){
// async.map will call this once per myarr element, until completion or error
myFunc(d, function(err, data){
done(err, data);
});
};
function mapCallback(err, mapped){
// async.map will call this after completion or error
if(err){
// Async ALREADY broke the loop for you.
// Execution doesn't continue if the iterator function callsback with an
// error.
};
console.log("Asynchronous result of passing mydata to myfunc:");
console.log(mapped);
// mapped is an array of returned data, in order, matching myarr.
};
function myFunc (arg1, callback) {
async.waterfall(
[
function(done) {
//do something
done(null, data);
},
function(data, done) {
//do something
done(null, 'done');
}
],
function(err, result) {
if (result !== 200) {
return callback('Non-200');
// This return is important to end execution so you don't call the callback twice
}
callback(err, result);
}
}
您正在尝试混合同步和异步控制流。问题是,你对myFunc的调用将在myFunc内部的瀑布函数执行之前立即返回。
下面是一个真实的例子。它遍历数组,如果看到5,则以错误结束:
var async = require('async');
function myFunc(data, cb) {
async.waterfall(
[
function(callback) {
//do something
callback(null, data);
},
function(data, callback) {
//do something
if (data === 5) {
callback("Five", null); // Throw error if we see 5
} else {
callback(null, 'done');
}
}
],
function(err, result) {
cb(err, result);
}
);
}
var mydata = [1,2,3,4,5,6];
async.eachSeries(mydata, function(d, cb) {
console.log('Processing ' + d);
myFunc(d, cb);
}, function(err) {
// error happened in processing d
// handle error
console.log('Error ' + err);
});