1.如果在第二个function中不使用异步的话,end会先被打印。原因如下
parallel(any function in async)
is about kicking-off I/O tasks in parallel, not about parallel execution of code. If your tasks do not use any timers or perform any I/O, they will actually be executed in series. Any synchronous setup sections for each task will happen one after the other. JavaScript remains single-threaded.
var async = require("async"); async.filter([1, 2, 3], function (item, callback) { async.nextTick(function(){ if(item % 2 != 0){ callback(true); }else callback(false); }); }, function (result) { console.log(result); }); console.log("end");
2.async有NAME版本和NAMESeries版本,带Series版本的都是等待前一次迭代结束(即call了callback)后才会执行,就是说他是按顺序执行的。不加Series不按顺序执行,但是最后的返回值顺序和传入值保持一致。
3.async.filter,async.reject的第二个参数的callback调用时没有error参数,只可传入true或者false。所以第三个参数的function也不接受error参数。
4. reduce是自动序列化的。即不存在reduceSeries。除此之外,reduce过程还可以自右向左,recudeRight
var async = require("async"); var arr = [1, 2, 3]; //reduce是序列化的,不需要reduceSeries async.reduce(arr, 1, function (memo, item, callback) { console.log(item); callback(null, memo * item); }, function (err, result) { console.log(result); });
5.async.detect发现数组中第一个元素符合条件就退出。没有顺序,谁第一个callback(true)就是谁,如果要保持顺序,调用async.detectSeries
同理async.some的callback返回值为true如果有一个元素满足条件,async.every则为所有
var async = require("async"); //结果不是2,就是3.如果加上detectSeries,结果就一直为2 async.detect([2, 3, -1], function (ele, callback) { //把这里的detect设为some或者every也可以 var random = Math.random() * 1000; setTimeout(function () { if (ele > 1) { callback(true); } else { callback(false); } }, random); }, function (result) { console.log(result); });
6.sortBy根据一定规则排序
/** * Created by qiucheng on 15/8/27. */ var async = require("async"); var arr = [3, 4, 3.5, 1.2]; async.sortBy(arr, function (ele, callback) { //和PI之间的距离 callback(null, Math.abs(Math.PI - ele)); }, function (err, result) { console.log(result); });
7.async.series方法,按顺序执行,返回值是每次执行的结果所组成的数组。如果第一个参数不是函数数组,而是一个对象的话,返回值就不一样了,见图2.
async.series,async.parallel(并行执行IO任务),async.waterfall(前一个结果能够传入后一个函数)的接口风格都是async.**(functionArray,catchAllFunction)
asyncseries// do some stuff ...callbacknull 'one';// do some more stuff ...callbacknull 'two';// optional callback// results is now equal to ['one', 'two'];
// an example using an object instead of an arrayasyncseriessetTimeoutcallbacknull 1;200;setTimeoutcallbacknull 2;100;// results is now equal to: {one: 1, two: 2};
8. 类似于while循环,类似的还有async.until(测试函数为true时停止),async.dowhilst(类似于doWhile,test函数和第二个函数交换顺序)
var async = require("async"); var count = 0; async.whilst( //test函数 function(){ //while循环条件,false时退出整个async流程 return count < 3; }, function(callback){ setTimeout(function(){ count++; console.log("oh yeah"); callback(); //调用callback再次进入test函数,如果不调用callback,整个流程直接结束,不会进入第三个函数 //或者也可以调用callback(err) },10) }, function(err){ if(err){ console.log(err); }else{ console.log("finished"); } } );
9.async.during,和whilist类似,但是他的test函数是异步的,
var async = require("async"); var count = 0; async.during( //这个函数是异步的,需要调用他的callback方法 function (callback) { setTimeout(function () { console.log(count + " ? " + 3); callback(null, count < 3); }); }, function (callback) { setTimeout(function () { count++; console.log(count); callback(); }); }, function (err) { if (err) { console.log(err); } else { console.log("finished"); } } );
10.async.forever,永远执行下去,除非传给next函数的第一个参数不是null
asyncforevernext(null);// if next is called with a value in its first parameter, it will appear// in here as 'err', and execution will stop.;
10.async.waterfall,前一个函数的执行结果将作为后一个结果的参数传入
var async = require("async"); var request = require("request"); var fs = require("fs"); async.waterfall( [ function (callback) {
//baidu的网页结果传入下一个函数 request("http://www.baidu.com", function (err, response, body) { if (err) { callback(err); return; } else { callback(null, body); } }); }, //第一个函数的返回值是第一个参数 function (webpageBody, callback) {
//用上一个函数的结果当做输出流的内容 fs.writeFile("test.html", webpageBody, function (err) { if (err) { callback(err); return; } else { callback(null); } }) }], function (err) { if (err) { console.log(err); return; } else { console.log("finished writing") } } );
11.async.compose=>使用 f(g()),需要注意的是,async.compose返回一个函数,执行时需要调用该函数,并且注意是否需要对该函数调用bind方法来绑定this
注意compose传入参数顺序和我们的直觉相反,async.seq和我们直觉相同
var async = require("async");
var testObj = {
addFactor: 2,
multiplyFactor: 5
};
var add = function (n, callback) {
var obj = this;
async.nextTick(function () {
callback(null, n + obj.addFactor);
});
};
var multiply = function (n, callback) {
var obj = this;
async.nextTick(function () {
callback(null, n * obj.multiplyFactor);
});
};
//multiply和add中有this引用,需要bind到一个对象上//(3 + 2) * 5
var composeFunc = async.compose(multiply, add).bind(testObj);composeFunc(3, function (err, result) { if (err) { console.log(err); } else { console.log(result); }});
//(3 * 5) + 2
var sequenceFunc = async.seq(multiply, add).bind(testObj); sequenceFunc(3, function (err, result) { if (err) { console.log(err); } else { console.log("seqeucne " + result); } });
12.async.applyEach/applyEachSeries
var async = require("async"); async.applyEach( [ function (arg, callback) { console.log(arg + " in func1") callback(); }, function (arg, callback) { console.log(arg + " in func2") callback(); } ] , 10, function (err) { if (err) { console.log(err); } else { console.log("finished") } } );