koa源码分析-co模块以及thunk
Thunk以及CO模块
co4.0之前都是返回的thunk函数
之后的都是返回promise
thunk
thunk:在 JavaScript 语言中,Thunk 函数替换的是将多参数函数,替换成单参数的版本,且只接受回调函数作为参数。
// 正常版本的readFile(多参数版本)
fs.readFile(fileName, callback);// Thunk版本的readFile(单参数版本)
var readFileThunk = Thunk(fileName);
readFileThunk(callback);var Thunk = function (fileName){return function (callback){return fs.readFile(fileName, callback); };
};
生产环境中,可以使用thunkify将函数转换为thunk 函数
问题:
为什么node 里面大部分的callback都是第一个参数是err呢?
为什么要做thunk 转换呢?
在redux里面也有thunk middleware,这个thunk是什么意思呢?
CO 模块
co的原理很简单,就是将传入的generator function 转换为一个thunk,并且转换后thunk 的generator的每个value值作为下一个状态的输入
function co(fn) {
var isGenFun = isGeneratorFunction(fn);return function (done) {//返回的thunk函数,done 作为回调函数var ctx = this;// in toThunk() below we invoke co()// with a generator, so optimize for// this casevar gen = fn;//gen function 转换为generatorif (isGenFun) {var args = slice.call(arguments), len = args.length;var hasCallback = len && 'function' == typeof args[len - 1];done = hasCallback ? args.pop() : error;gen = fn.apply(this, args);} else {done = done || error;}//函数执行的时候就会执行next函数,进入函数体里面next();// #92// wrap the callback in a setImmediate// so that any of its errors aren't caught by `co`function exit(err, res) {setImmediate(done.bind(ctx, err, res));}function next(err, res) {var ret;// multiple argsif (arguments.length > 2) res = slice.call(arguments, 1);// errorif (err) {try {ret = gen.throw(err);} catch (e) {return exit(e);}}// okif (!err) {try {ret = gen.next(res);} catch (e) {return exit(e);}}// doneif (ret.done) return exit(null, ret.value);// normalizeret.value = toThunk(ret.value, ctx);// runif ('function' == typeof ret.value) {var called = false;try {//比如执行yield readFile('test.json'), ret.value就是readFile函数,函数接受一个callback,callback调用next方法,讲readFile的结果传入了next函数ret.value.call(ctx, function(){//这里可以防止next函数被多次执行if (called) return;called = true;next.apply(ctx, arguments);});} catch (e) {setImmediate(function(){if (called) return;called = true;next(e);});}return;}// invalidnext(new Error('yield a function, promise, generator, array, or object'));}} }
通过上面的co源码分析,可以看下面的例子
co(function *() {var file = yield readFile('test.json');//这里的file是通过gen.next() 赋值的console.log(file);var ret = yield writeFile(file, 'dest.json');console.log(ret); })
了解了这些基本概念后就可以进入koa的源码阅读了,具体的可以参考下一篇。
koa源码分析-co模块以及thunk相关推荐
- Koa源码分析(二) -- co的实现
Abstract 本系列是关于Koa框架的文章,目前关注版本是Koa v1.主要分为以下几个方面: Koa源码分析(一) -- generator Koa源码分析(二) -- co的实现 Koa源码分 ...
- koa源码分析-generator和yield分析
Generator和yield 分析 项目中使用了koa,最近在学习koa的源码,先把这些东西都写下来,免得以后忘记了. koa源码学习前先注意下面这三个概念 generator function ( ...
- Python3.5源码分析-sys模块及site模块导入
Python3源码分析 本文环境python3.5.2. 参考书籍<<Python源码剖析>> python官网 Python3的sys模块初始化 根据分析完成builtins ...
- nginx源码分析之模块初始化
在nginx启动过程中,模块的初始化是整个启动过程中的重要部分,而且了解了模块初始化的过程对应后面具体分析各个模块会有事半功倍的效果.在我看来,分析源码来了解模块的初始化是最直接不过的了,所以下面主要 ...
- Fabric源码分析-共识模块
正好这些天要有一个需求要帮客户魔改Fabric-v0.6,把一些hyperchain的高级特性移植过去,借此机会把之前看过的源码在梳理一下. 下面就是对Fabric共识模块的源码分析和梳理,代码都是以 ...
- [Abp vNext 源码分析] - 2. 模块系统的变化
一.简要说明 本篇文章主要分析 Abp vNext 当中的模块系统,从类型构造层面上来看,Abp vNext 当中不再只是单纯的通过 AbpModuleManager 来管理其他的模块,它现在则是 I ...
- Canal源码分析deployer模块
canal有两种使用方式:1.独立部署 2.内嵌到应用中. deployer模块主要用于独立部署canal server.关于这两种方式的区别,请参见server模块源码分析.deployer模块源码 ...
- 5章 性能平台GodEye源码分析-第三方模块
5. 第三方模块 5.1 Crash(XCrash) Crash监控崩溃后的堆栈上传,作者采用接入爱奇艺的XCrash框架 源码分析 1.启动Crash的监控 Crash的监控通过反射启动XCrash ...
- WebRTC源码分析——Call模块
目录 1. 引言 2. Call对象的创建 2.1 创建CallFactory对象 2.2 创建Call对象 2.2.1 PeerConnection.CreateCall_w 2.2.2 CallF ...
最新文章
- 要立刷金组flag了T_T
- linux脚本外输入参数,shell 脚本中关于用户输入参数的处理
- 微软翻译突破百种语言和方言大关
- 开源社区ITGeek介绍
- Hadoop学习笔记—2.不怕故障的海量存储:HDFS基础入门
- [转载] 菜鸟举例理解字节流和字符流区别
- sql server查询某一字段不重复的数据_初识数据库
- 深度召回算法在字节跳动推荐系统的应用实践
- 太慢不能忍!CPU 又拿硬盘和网卡开刀了!
- ubuntu安装中文字体,python plt 绘图显示中文
- python-random
- 大众点评字WOFF字体解密
- su室外渲染参数设置_vray for sketchup渲染材质参数设置教程
- 秋叶一键重装系统连接服务器失败,小熊教你如何解决一键重装系统失败问题
- bootice.exe linux 启动盘,下载BOOTICE来把你的U盘做成启动盘
- MySql round用法
- B站小甲鱼零基础python视频P57爬取煎蛋网OOXX妹纸图代码修改
- 神奇的「种子法则」:意念具有不可思议的超能量
- Windows内核--Rtl字符串API “不同IRQL“(3.2)
- 转 Java知识——精华总结
热门文章
- python3.7.4安装教程桌面_Python 3.7.4 for Windows的安装
- date类型_06076.1.0如何将ORC格式且使用了DATE类型的Hive表转为Parquet表
- SearchHit转成java对象_Java开发中最常犯的10个错误,你中招了吗?
- 线性表List的基本创建
- lua菜鸟教程_Lua 环境安装
- 小程序客服自动回复图片,云开发的实现
- JS实现HTML标签转义及反转义
- vue组件定义、组件的切换、组件的通信、渲染组件的几种方式(标签、路由、render)...
- 个人项目-小学四则运算 “软件”之初版
- opencv3 图像处理(一)图像缩放( python与c++ 实现)