针对JS的异步机制,JS社区给出了很多不同的解决方案,Async库便是其中一种,可能也是对于控制异步操作最全面的资源。因为该库提供了70个函数,几乎想所有的运用场景都考虑在内。以下笔者针对四个函数进行讲解:
1. parallel
const async = require('async');
const doOne = callback => {
setTimeout(() => {
callback(null, 'one');
}, 1000)
}
const doTwo = callback => {
setTimeout(() => {
callback(null, 'two');
}, 1000)
}
let array = [];
array.push(doOne);
array.push(doTwo);
async.parallel(array, (err, result) => {
console.log(result);
})
//等待1秒后打印:['one', 'two']
Parallel 函数接受两个参数,第一个参数可以是数组也可以是对象。里边需要包括所有需要并行操作的异步函数,以上图为例,笔者将两个异步函数,setTimeout加入队列中,然后放入parallel函数内的第一个参数。需要注意的是每个异步函数需要制定一个固定参数callback进行调用。该函数用来检测任何错误信息和最后传达到parallel第二个参数的result。以上函数的执行结果是在等待一秒之后打印出队列,里面包含了‘one’和'two'两值。如果将以上的array改成一个对象,那result也会是一个对象,并根据传入的键值给结果附上对应的值。
2. series
const async = require('async');
const doOne = callback => {
setTimeout(() => {
callback(null, 'one');
}, 1000)
}
const doTwo = callback => {
setTimeout(() => {
callback(null, 'two');
}, 1000)
}
let array = [];
array.push(doOne);
array.push(doTwo);
async.series(array, (err, result) => {
console.log(result);
})
//等待2秒后打印:['one', 'two']
以上的代码和parallel几乎一样,唯一改变的是将parallel函数改成series。但执行结果却从1秒变为2秒。Series针对数组的顺序去调用异步函数,只有当第一个函数执行完成后才会调用第二个,所以执行时间会延长到2秒。但一般情况下,如果业务逻辑需要几个异步操作通过顺序进行,那么很有可能排后的函数需要用到先执行函数的结果,而series并没有给出传递参数给下一个函数的功能。在这样的情况,开发者可以用waterfall来解决;
3. waterfall
const doOne = callback => {
callback(null, "one");
}
const doTwo = (arg, callback) => {
console.log(arg);
callback(null, "two");
}
let array = [];
array.push(doOne);
array.push(doTwo);
async.waterfall(array, (err, result) => {
console.log(result);
})
//one
//two
跟其他函数不同waterfall会将数组里第一个函数传入callback的值传递给下一个函数。doTwo里面的console.log会打印doOne传入的“one”,而waterfall里的回调会打印doTwo传入的“two”。
4. whilst
var count = 0;
async.whilst(
function() { return count < 10; },
function(callback) {
count++;
console.log(count);
setTimeout(function() {
callback(null, count);
}, 500);
},
function (err, n) {
console.log('done');
}
);
whilst跟以上三个函数不同,该操作不是针对数组或者对象内的顺序进行异步调用,而是针对在某种条件下执行异步操作。whilst接受三个参数,第一个为判断函数,只有在该函数返回true时,第二个参数参会执行。第二个参数便是表达核心逻辑的函数。第三个则是第一个参数返回false之后的回调函数。在上面的例子中,whilst控制住了count的打印速度,会在每半秒打印出一次count。