网页设计学习笔记

HTML,CSS,JavaScript

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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

posted on 2013-05-10 23:53  zoho  阅读(1084)  评论(0编辑  收藏  举报