Async源码分析

简介:

最近在使用到node js的async库的时候,对其waterfall的实现感觉很奇妙,于是看了一下源码:

    async.waterfall = function (tasks, callback) {
        callback = callback || function () {};
        if (!_isArray(tasks)) {
          var err = new Error('First argument to waterfall must be an array of functions');
          return callback(err);
        }
        if (!tasks.length) {
            return callback();
        }
        var wrapIterator = function (iterator) {
            return function (err) {
                if (err) {
                    callback.apply(null, arguments);
                    callback = function () {};
                }
                else {
                    var args = Array.prototype.slice.call(arguments, 1);
                    var next = iterator.next();
                    if (next) {
                        args.push(wrapIterator(next));
                    }
                    else {
                        args.push(callback);
                    }
                    async.setImmediate(function () {
                        iterator.apply(null, args);
                    });
                }
            };
        };
        wrapIterator(async.iterator(tasks))();
    };
 

开始先对参数进行了检查,判断tasks是否是一个function数组。然后使用了一个内部函数wrapIterator封装了实现。wrapIterator的参数带出了async.iterator函数:

 
    async.iterator = function (tasks) {
        var makeCallback = function (index) {
            var fn = function () {
                if (tasks.length) {
                    tasks[index].apply(null, arguments);
                }
                return fn.next(); //这个地方有必要么???
            };
            fn.next = function () {
                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
            };
            return fn;
        };
        return makeCallback(0);
    };


这个函数,其主要实现是其内部函数makeCallback。其功能就是迭代tasks,封装其中的每一个function,让其执行后返回下一个function,以此实现迭代。

接下来,再回到wrapIterator,此function是对iterator的封装。执行后返回的是一个匿名function。其明确的参数只有一个err。当err不为空的时候,直接执行callback function。否则从index为1开始取出参数列表,并把iterator的下一个function包装之后push到args中(如果没有下一个function了则push回调函数)。接下来,则执行当前的iterator,执行的参数是下一个iterator function(作为这一步的回调函数)以及参数(如果当前的iterator被调用时传递了其他参数)。这样在当前iterator中回调下一个iterator,依次迭代执行,直至执行完所有function和callback。









原文出处:后端技术杂谈
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。
目录
相关文章
|
6月前
|
缓存 Java Spring
异步编程 - 09 Spring框架中的异步执行_@Async注解异步执行原理&源码解析
异步编程 - 09 Spring框架中的异步执行_@Async注解异步执行原理&源码解析
33 0
|
3月前
|
前端开发
【面试题】说说你对 async和await 理解
【面试题】说说你对 async和await 理解
|
3月前
|
前端开发 JavaScript 索引
【面试题】对async/await 的了解?
【面试题】对async/await 的了解?
|
7月前
|
前端开发
前端(十二)——深入理解和使用 async和await
前端(十二)——深入理解和使用 async和await
|
7月前
|
存储 Dart 数据库
Dart异步之Future以及async、await的使用
Dart异步之Future以及async、await的使用
114 2
|
8月前
|
前端开发 JavaScript
async、await 实现原理
async、await 实现原理
52 1
|
8月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(三)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(三)
|
8月前
|
前端开发 JavaScript API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(一)
Promise(简介、基本使用、API、手写实现 Promise、async与await)
|
8月前
|
前端开发 API
Promise(简介、基本使用、API、手写实现 Promise、async与await)(六)
Promise(简介、基本使用、API、手写实现 Promise、async与await)(六)
|
12月前
|
消息中间件 Android开发
Handler postDelayed的实现原理
老生常谈之Handler
98 0