Node.JS 异步模块的使用

Node.JS 中的一大麻烦就是异步函数太多,导致程序的流程不好控制。但是,有了 async 模块,这个问题不再是问题了。这里我们总结下 async 模块的用法。

假如我们需要分别读取两个文件的内容,如果两者都成功就执行其它操作。如果按照同步的思路,代码如下:

function task1() {

    fs.readFile('somefile', function(err, data) {

        if (err) throw err;

        window.data1 = data;

        console.log('task1 done!');

    });

}



function task2() {

    fs.readFile('morefile', function(err, data) {

        if (err) throw err;

        window.data2 = data;

        console.log('task2 done!');

    });

}



function then() {

    var data1 = window.data1;

    var data2 = windos.data2;

    console.log(data1 + data2);

    console.log('both tasks done!'); 

}



task1();

task2();

then();

但是现在 readFile 是异步函数,这样的代码是错误的:因为它将导致函数 then 的结果先输出。要改为正确的写法需要函数的嵌套,很繁琐也难看。现在改为 async 模块的写法就简单多了:

async.parallel([

    function(callback){

        fs.readFile('somefile', function(err, data) {

            console.log('task1 done!');

            callback(err, data);

        });

    },

    function(callback){

        fs.readFile('morefile', function(err, data) {

            console.log('task2 done!');

            callback(err, data);

        });

    }

],

function(err, results){

    if (err) throw err;

    var data1 = results[0];

    var data2 = results[1];

    console.log(data1 + data2);

    console.log('two tasks done!'); 

});

这里用到 async 的 parallel 这个同步执行的函数,它保证前面的两个函数都执行完毕后才执行原来函数 then 的内容。另外你会注意到这种用法的关键之处:并行执行的每个函数都必须有 callback 参数,这个 callback 参数负责在该函数最后提供出错信息和返回值给 parallel 函数。因此,这个 callback 函数一定要调用它,即使没有出错信息和返回值也应该在最后用 callback()。

如果前面两个任务的 console.log 不需要,上面的代码还可以简化如下:

async.parallel([

    function(callback){

        fs.readFile('somefile', callback);

    },

    function(callback){

        fs.readFile('morefile', callback);

    }

],

function(err, results){

    if (err) throw err;

    var data1 = results[0];

    var data2 = results[1];

    console.log(data1 + data2);

    console.log('two tasks done!'); 

});

这是因为 async 任务的回调函数和 Node.JS 异步操作的回调函数参数是一致的:都是 error 和 data 这两个。这样写起来就更加简洁漂亮了。

async 还有更多的函数,比如 series,waterfall,auto,each 等等其它控制异步执行流程的函数,它们的用法和上面的例子类似。

参考资料:
[1] caolan/async - Async utilities for node and the browser
[2] Node.js async in practice: When to use what?
[3] Async详解之一:流程控制 | Freewind.me
[4] Async详解之二:工具类 | Freewind.me
[5] Async详解之三:集合操作 | Freewind.me
[6] node.js async.series not working - Stack Overflow
[7] Asynchronous code in node.js

你可能感兴趣的:(node.js)