async.waterfall(tasks,callback)
瀑布流函数,串行执行数组中的每一个函数最后执行回调。
第一个参数tasks是一个数组,数组包含的是需要依次执行的函数名。
第二个参数为回调函数,当瀑布流函数执行出现错误时会执行这个回调函数并将错误信息返回,当瀑布流函数无错误时,会在执行完tasks数组中包含的函数后执行这个回调函数。
自我感觉async最好用的流程控制方法,可大大降低代码耦合度。(一个函数只做一件事,async.waterfall则实现了一系列函数的异步组合)
一般用法:
async.waterfall([
myFirstFunction,
mySecondFunction,
myLastFunction,
], function (err, result) {
// result now equals 'done'
});
function myFirstFunction(callback) {
callback(null, 'one', 'two');
}
function mySecondFunction(arg1, arg2, callback) {
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
}
function myLastFunction(arg1, callback) {
// arg1 now equals 'three'
callback(null, 'done');
}
匿名函数的异步控制:
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
},
function(arg1, callback) {
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
async.waterfall(tasks,callback)
tasks并行运行函数集合,而不必等到上一个函数完成。如果任何函数发生错误,会立刻执行回调函数,并返回错误信息;若没有发生错误,则会在所有tasks函数执行完毕之后用回调函数将结果返回。
代码示例:
async.parallel([
function(callback) {
setTimeout(function() {
callback(null, 'one');
}, 200);
},
function(callback) {
setTimeout(function() {
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results) {
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});
async.eachSeries(coll,iteratee,callback)
简单地说,是用来异步执行一系列的操作,保证每次遍历都执行完毕后再执行下一次的操作,非常有用。
第一个参数可以是一个数组或一个对象(用来遍历)。
第二个参数是每次遍历执行的函数。
第三个参数是回调函数,当遍历中出错会立刻执行回调函数并返回错误信息,若没有发生错误则会等遍历结束后将正确的结果返回。
如果概念不好理解那就请对比下面的两段代码.
第一段代码,foreach里面嵌套save方法,触发异步陷阱,并且mongoose的数据库锁机制(每次操作数据库时会锁定这个库直到本次操作结束)会,出现逻辑错误。
books.foreach(book,function(){
book.price = parseFloat(book.listPrice) || book.price || 0;
book.listPrice = undefined;
book.save(function (err, book) {
console.log(book.name);
});
});
第二段代码,利用async.eachSeries巧妙地完成了异步流程控制,也就是每一个save操作完成后再进行下一次遍历。
async.eachSeries(books, function (book, callback) {
book.price = parseFloat(book.listPrice) || book.price || 0;
book.listPrice = undefined;
book.save(function (err, book) {
console.log(book.name);
callback(err);
});
}, function (err) {
if(err){
config.error(err);
done(err);
}else{
config.info('update price successful');
done(null);
}
});
}
以下方法更新于 9/5/2017
map(coll, iteratee, callbackoption)
代码示例
it('async map', done => {
var totalArr = [56, 56, 56, 21, 32];
async.map(totalArr, (arr, cb) => {
arr--;
console.log(arr);
cb(null, arr);
}, (err, result) => {
//当err存在,则执行foo(err)错误处理函数,否则不执行
err && foo(err);
console.log(result);
done();
});
})
代码解析:将数组传入后async.map遍历,每项减一,然后返回新的数组。
whilst(test, iteratee, callbackopt)
var totalArr = [56, 56, 56, 21, 32];
async.whilst(function () {
return totalArr.length>0;
}, (cb) => {
totalArr.pop();
console.log(totalArr);
cb(null,totalArr);
}, (err, result) => {
err && foo(err);
console.log(result);
done();
});
以上代码主要实现了循环将数组尾部项弹出,完全可以用while循环实现,在这里有点大材小用。。。控制台输出效果如下:
[ 56, 56, 56, 21 ]
[ 56, 56, 56 ]
[ 56, 56 ]
[ 56 ]
[]
[]
想了解更多请参考async官网文档:https://caolan.github.io/async/docs.html#