异步的那些事儿,async

2015-04-18  本文已影响221人  忧郁的河蟹

回调,是每个nodejser必须面对的问题,社区也有很多解决方案,诸如asnyc,promise和ECMAScript 第六版的引入。异步的那些事儿,讲会围绕这三个方案来展开。

async

项目地址:https://github.com/caolan/async
async是最早在node.js社区流行的异步库,其简单的语法和相对绿色的封装,深受node.jser所爱,也是本人最常用的异步库。

相信语法这种东西,文档会比我描述得更详细,本文不会过多地介绍语法问题,侧重实现原理。下面将以几个本人认为比较经典的例子作为展开。

async核心代码

// assuming openFiles is an array of file names and saveFile is a function
// to save the modified contents of that file:

async.each(openFiles, saveFile, function(err){
    // if any of the saves produced an error, err would equal that error
});

上面的函数,会遍历openFiles的数组,对文件进行读取,当全部文件内容都读取完毕后,执行最后的回调函数。

async.each = function (arr, iterator, callback) {
        callback = callback || function () {};
        if (!arr.length) {
            return callback();
        }
        var completed = 0;
        _each(arr, function (x) {
            iterator(x, only_once(done) );
        });
        function done(err) {
          if (err) {
              callback(err);
              callback = function () {};
          }
          else {
              completed += 1;
              if (completed >= arr.length) {
                  callback();
              }
          }
        }
    };

async.each(openFiles, saveFile, callback) 读取openFiles的数组长度,创建completed作为哨兵变量,每完成一件saveFile任务后,completed 自增1,当 completed 的大小等于 openFiles 的数组长度的时候,代表任务结束,回调函数。

实现非常简单,本人也实现了一个版本,可以参考一下。

var fs = require('fs');

async = {
    map: function (arrs, iter, callback) {
        var length = arrs.length;
        var count = 0; //哨兵变量
        var result = [];  //结果缓存

        var next = function (err, data) {
            if (err) {
                return callback(err); // 遇到错误马上跳出
            }

            result.push(data);
            count += 1;

            if (count === length) {
                return callback(err, result);
            }
        };

        arrs.forEach(function (arr) {
            iter.call(null, arr, next);
        })
    }

};

async.map(['1.txt', '2.txt', '3.txt'], function (filename, next) {
    fs.readFile(filename, 'utf-8', next);
}, function (err, result) {
    console.log(result);
    console.log('fin');
});

源码:
https://github.com/youyudehexie/nodejs-cookbook/blob/master/async/demo1.js

上一篇下一篇

猜你喜欢

热点阅读