原文链接:http://www.srhang.me/blog/2014/08/22/node-async-analysis/
最近在使用到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开始取出参数列表(第一个默认传递err),并把iterator的下一个function包装之后push到args中(如果没有下一个function了则push回调函数)。接下来,则执行当前的iterator,执行的参数是下一个iterator function(作为这一步的回调函数)以及部分参数(如果当前的iterator被调用时传递了多余一个的参数)。这样在当前iterator中回调下一个iterator,依次迭代执行,直至执行完所有function和callback。
相关推荐
webpack源码分析 webpack的本质和Tapable介绍 Tapable中的Sync *类型的钩子 Tapable中的Async *类型的钩子 webpack事件流 编译和编译对象介绍 编译和建造主流程 通过发出输出生成资源到Path 写一个简易的webpack ...
集合源码分析 JavaDemo 我的java演示代码 用于练习和记一些小demo 其中包含 项目 邮件的发送,附带文件的邮件发送 Zip文件压缩并加密 定时任务 Scheduled 事件监听 事件监听需要 触发器->事件源->监听器 触发器【触发...
异步任务Asynctask源码与反编译对比,来分析源代码
项目亮点 采用 pandas、numpy 进行数据分析 基于 snownlp、jieba 进行情感分析 ...前端采用 Promise、async、await 进行异步请求 展示地址 主页:https://python.sinwer.cn/ 数据接口:https://python.sinwer.cn/v1/
@ cloudflare / worker-sentry 工人通行哨兵安装npm install -D @cloudflare/worker-sentry例子 import { ...async function handleRequest ( request , sentry ) { try { console . log ( "Got request" , request ) ;
前端进阶JavaScript基础:JavaScript数据类型JavaScript代码运行机制作用域和作用域链let/const/var的区别JavaScript高阶编程技巧原型和原型链的底层运行机制this指向数据...axios源码分析设计模式:手写发布订阅模式
resume-native 个人简历原生实现版本 ...co源码分析 其实开始对generator感兴趣,正是由写这个会动的简历开始,一步步弄明白了怎么使用,以及通过它来解决一些异步流程控制问题。而这个东西是什么呢?其正
本文实例讲述了Sanic框架请求与响应。分享给大家供大家参考,具体如下: 前面介绍了Sanic框架的路由,这里接着介绍Sanic框架的请求与响应。 简介 Sanic是一个类似Flask的Python 3.5+ Web服务器,它的写入速度非常快...
你不知道ReactJS 你不知道Reactjs。 (书)
03.SpringMVC源码角度分析@async失效之谜(141分钟) 04.使用装饰模式设计分布式多级缓存框架(82分钟) 05.使用观察者模式设计异步多渠道群发框架(82分钟) 06.深入研究单例模式底层原理与防止破解(189分钟) 07.基于责任...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
G3log:具有动态接收器的异步记录器 使用g3log的示例项目 静态和动态构建的g3log的示例项目集成可以在找到 用法示例 可选使用流式或类似printf的语法 LOG(INFO) << "streaming API is as easy as ABC or " <...
明显更快 同时撰写API + Options API支持,并进行输入 基于代理的变更检测 碎片 门户网站 带有w / async setup() 但是,仍有一些2.x奇偶校验功能尚未完成: 服务器端渲染 <keep> <transition> 带有过渡的v-show ...
起因 最近在学习koa的使用, 由于koa是相当基础的web框架,...所以我决定通过源码来分析二者中间件实现的原理以及用法的异同。 为了简单起见这里的express用connect代替(实现原理是一致的) 用法 二者都以官网(github
不过本篇文章,并不是源码分析,而是从相反的角度,向大家展示如何从头开发实现一个koa框架,在这个过程中,koa中最重要的几个概念和原理都会得到展现。相信大家在看完本文之后,会对koa有一个更深入的理解,同时在...
Koa作为下一代Web开发框架,不仅让我们体验到了async/await语法带来同步方式书写异步代码的酸爽,而且本身简洁的特点,更加利于开发者结合业务本身进行扩展。 本文从以下几个方面解读Koa源码: 封装创建应用程序...
书名:《Delphi串口及语音传真高级编程》(北京航空航天... 9.3 源码分析 9.3.1 动态连接库模块 9.3.2 截取api的公共单元 9.3.3 主程序模块 附 录 附录a 组件的安装 附录b at命令一览表
3.4.2 事件分发的源码解析 / 144 3.5 View的滑动冲突 / 154 3.5.1 常见的滑动冲突场景 / 155 3.5.2 滑动冲突的处理规则 / 156 3.5.3 滑动冲突的解决方式 / 157 第4章 View的工作原理 / 174 4.1 初识View...