koa源代码解析
koa不愧为小而美,主要代码很少。简单来说,
1,koa封装了node的http.createServer((req,res)=>{})的入参req,res到ctx同名属性(一个自定义对象)中,
并且额外提供了ctx.request,ctx.request提供一些快捷的操作。
const app = new Koa()
app.use(middlewareFn)
2.方法use函数接收参数fn,放入中间件middleware[]数组里面。
use(fn) {
this.middleware.push(fn);
return this;
}
通过用户调用listen(port)调用this.handleRequest函数:
listen(...args) {
const server = http.createServer(this.callback());
return server.listen(...args);
}
callback() {
const fn = compose(this.middleware);
const handleRequest = (req, res) => {
const ctx = this.createContext(req, res);
return this.handleRequest(ctx, fn);
};
return handleRequest;
}
调用处理过的middleware函数:
handleRequest(ctx, fnMiddleware) {
const res = ctx.res;
const handleResponse = () => respond(ctx);
return fnMiddleware(ctx).then(handleResponse).catch(onerror);
}
即处理过的middleware数组:
function compose (middleware) {
return function (context, next) {
// last called middleware #
let index = -1
return dispatch(0)
function dispatch (i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i
let fn = middleware[i]
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
递归的展开就是洋葱模型了:
const [fn1, fn2, fn3] = this.middleware;
const fnMiddleware = function(ctx){
return Promise.resolve(
fn1(context, function next(){
return Promise.resolve(
fn2(context, function next(){
return Promise.resolve(
fn3(context, function next(){
return Promise.resolve();
})
)
})
)
})
);
};
fnMiddleware(ctx).then(handleResponse).catch(onerror);
ctx:
createContext(req, res) {
const context = Object.create(this.context);
const request = context.request = Object.create(this.request);
const response = context.response = Object.create(this.response);
context.app = request.app = response.app = this;
context.req = request.req = response.req = req;
context.res = request.res = response.res = res;
request.ctx = response.ctx = context;
request.response = response;
response.request = request;
context.originalUrl = request.originalUrl = req.url;
context.state = {};
return context;
}
koa源代码解析的更多相关文章
- Spring源代码解析
Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的启动:http://www.itey ...
- Arrays.sort源代码解析
Java Arrays.sort源代码解析 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类 ...
- Spring源代码解析(收藏)
Spring源代码解析(收藏) Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的 ...
- volley源代码解析(七)--终于目的之Response<T>
在上篇文章中,我们终于通过网络,获取到了HttpResponse对象 HttpResponse是android包里面的一个类.然后为了更高的扩展性,我们在BasicNetwork类里面看到.Volle ...
- Cocos2d-x源代码解析(1)——地图模块(3)
接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInf ...
- Android EventBus源代码解析 带你深入理解EventBus
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40920453,本文出自:[张鸿洋的博客] 上一篇带大家初步了解了EventBus ...
- 源代码解析Android中View的layout布局过程
Android中的Veiw从内存中到呈如今UI界面上须要依次经历三个阶段:量算 -> 布局 -> 画图,关于View的量算.布局.画图的整体机制可參见博文 < Android中Vie ...
- Android xUtils3源代码解析之网络模块
本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...
- Android View体系(八)从源代码解析View的layout和draw流程
相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...
- 《nginx源代码解析》系列分享专栏
<nginx源代码解析>系列分享专栏 解析nginx源代码,从main函数开始,一步步解读nginx运行原理,同时进行nginx第三方模块的开发,努力做到知其然,知其所以然 <ngi ...
随机推荐
- 【转载】Python(cx_oracle)的DPI-1047错误
转自:https://blog.csdn.net/weixin_45158749/article/details/124800132 Python(cx_oracle)的DPI-1047错误 步步 F ...
- SVN的安装和使用手册2
转载:http://www.cnblogs.com/armyfai/p/3985660.html SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需 ...
- Java--Comparable接口实现,控制数组和列表的排序
实现Comparable 接口,可以获得的排序方法有 列表排序 Collections.sort(); 数组排序 Arrays.sort(); sort()方法中的参数是可以获取排序索引的对象或者按照 ...
- kvm 透传显卡至win10虚拟机
环境 已安装nvidia 显卡 驱动 操作系统:CentOS Linux release 7.9.2009 (Core) 内核版本:Linux 5.4.135-1.el7.elrepo.x86_64 ...
- Chrome浏览器崩溃
1.使用Win+R打开运行对话框,输入regedit,点击确定打开注册表: 2.找到"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome&q ...
- java正则解析ip
public class test { public static void main(String[] args) { // TODO Auto-generated method stub Stri ...
- 代码随想录训练营day 5|24.两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题02.07.链表相交 142.环形链表Ⅱ
24. 两两交换链表中的节点 题目链接:24. 两两交换链表中的节点 题目描述:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点.你必须在不修改节点内部的值的情况下完成本题(即,只能进行 ...
- fastlane iOS打包 安装与使用
1.安装 fastlane sudo gem install fastlane 2.进入工程目录下 终端输入 fastlane init 接着输入3 然后control + c退出 接着编写 Fast ...
- Mac 远程 屏幕共享 screen sharing
屏幕共享可以用于在局域网中控制另一台 Mac,也能通过 iMessage 在广域网环境下创建彼此的连接,用来指导和解决问题非常方便. 通过 Apple ID 来创建连接 1,Command+空格键 ...
- 2015 for Mac PDF编辑软件
开始前请先断开网络连接,断网,断网,断网! 开始前请先断开网络连接,断网,断网,断网! 开始前请先断开网络连接,断网,断网,断网! 编辑 1.软件下载完成后,打开软件包如上图五个文件(第1个是安 ...