async异步流程控制模块源码

 Collections 集合处理

async.forEachOf  |  eachOf(object, iterator, callback)

  • 实现功能:遍历object对象执行iterator,报错或遍历执行完成时调用callback(error);callback(error)函数的触发时机需要手动在iterator中设置。
  • 源码解读:_keyIterator函数借用闭包遍历对象或数组(闭包中缓存数组的index值、或对象属性集合的index值),执行时获取不同的index值展开遍历,遍历终止时返回null。iterator若为异步延迟函数,每次启动执行时completed+1,延迟完成调用only_once(done)函数时completed-1,completed在源码中发挥作用没那么明确。iterator函数的尾参only_once(done)通过内部函数封装后输出给使用者,实现类似Promise模块将resolve、reject函数封装后输出给模块的调用者。callback函数在内部的执行条件是在外部调用过程中携带error错误,或者key=null、completed=0,即遍历执行完毕。
async.forEachOf =
    async.eachOf = function (object, iterator, callback) {
        callback = _once(callback || noop);
        object = object || [];

        var iter = _keyIterator(object);
        var key, completed = 0;

        while ((key = iter()) != null) {// 反复执行闭包函数iter遍历对象
            completed += 1;
            // only_once(done)中调用外部函数callback,机理同Promise-resolve相似
            // 内部函数对外部函数的影响是参数
            iterator(object[key], key, only_once(done));
        }

        if (completed === 0) callback(null);

        function done(err) {
            completed--;
            if (err) {
                callback(err);
            }
            // Check key is null in case iterator isn't exhausted
            // and done resolved synchronously.
            else if (key === null && completed <= 0) {
                callback(null);
            }
        }
    };
  • 主要问题:报错不影响后续iterator函数执行,参看async.some方法实现的中断回调的执行,捕获到err时,生成status=false状态,根据status状态调用回调函数callback。参看async.applyEach针对数组元素为函数的特殊情况,函数参数相同。
  • 官方示例:遍历读取json文件,报错或单次读取操作完成时执行callback回调,区别是携带参数为err或null。

相关推荐