koa源代码解析
2024-10-10 02:38:07
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;
}
最新文章
- Java 多线程编程
- GJM :SqlServer语言学习笔记
- excel导出
- 计算机网络(6)-----运输层概述和UDP协议
- 【BZOJ1812】riv(多叉树转二叉树,树形DP)
- SQL Server 2014里的IO资源调控器
- 用 Java 实现断点续传 (HTTP)
- pycharm最新注册方法 pycharm最新激活方法 2016pycharm最新注册方法
- java三线程循环有序打印ABC
- 关于微软企业库中依赖注入容器Unity两种生成对象的实现u
- thinkphp3.2.2前后台公用类架构问题
- 构建一个基于 Spring 的 RESTful Web Service
- 10. 混淆矩阵、总体分类精度、Kappa系数
- codeforces432D Prefixes and Suffixes(kmp+dp)
- iOS视图控制器之间delegate传值教程
- 采用WindowManager添加您自己的自定义视图
- DOM操作中,遍历动态集合的注意事项。ex: elem.children
- 故障定位之查找附近点GeoHash研讨
- nodemailer + express + h5 拖拽文件上传 实现发送邮件
- hive on tez配置