ES6 提供了 Promise 来更方便的使用异步操作,
后续又出了 async 和 await 关键字,使 Promise 变得更加优雅,
Promise 自带的一些方法基本上能满足日常使用,但是处理复杂的异步就没辙了。

我找到了 async.js,内置的方法可以实现各种逻辑的异步操作,
这里记录常用的。

async.js

实现各种逻辑的异步操作库。
其中的 task(任务函数),都按照了 callback 形式,第一个参数为 err,第二个参数为 result。

Github

并行执行

// 其实这个用 Promise.all 也能实现
// 同时开始执行所有任务,等待所有任务都执行完毕后,执行最终 callback
// 每个任务的结果会作为一个数组,传入最终 callback
async.parallel([
    function(callback) {
        setTimeout(function() {
            callback(null, 'one');
        }, 200);
    },
    function(callback) {
        setTimeout(function() {
            callback(null, 'two');
        }, 100);
    }
], function(err, results) {
    console.log(results);
    // results is equal to ['one','two'] even though
    // the second function had a shorter timeout.
});

串行执行

// 一个接一个的执行任务
// 若全部完成后,调用最终的 callback,每个任务的结果会作为一个数组传入。
// 若中途失败,则会放弃后面的任务,调用最终的 callback。
async.series([
  function(callback) {
    setTimeout(function() {
      // do some async task
      callback(null, 'one');
    }, 200);
  },
  function(callback) {
    setTimeout(function() {
      // then do another async task
      callback(null, 'two');
    }, 100);
  }
], function(err, results) {
  console.log(results);
  // results is equal to ['one','two']
});
// 按照顺序依次执行
// 下一个任务会接收上一个任务的结果作为参数
// 最终 callback 会接收最后一个任务的结果作为参数
// 这是与 series 最大的不同
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'
});