koa-connect源码解析
文中提到的koa均为koa2
提到nodejs, 想必大家都知道express和koa.
express: 大
koa: 小
比较的的是功能, 社区, 中间件,相关资源等
这里我就专门说说中间件吧, 很多人可能说express插件丰富啊. 其实除了中间件, 其余什么的和express koa本身并没有多大关系, 不都是基于nodejs http(https)的封装嘛.
express中间件是非常的丰富, 但是提个醒, express的中间件是可以跑在koa下面的.到这里就要提到 koa-connect.
那么,我们就来简单看看这个koa-connect是怎么实现的.
其源码一共才38行, 一半多注释, 3个方法.
- koaConnect: 对外公布的方法, 对express的中间件的参数进行分析,分别调用noCallbackHandler和withCallbackHandler
- noCallbackHandler : 处理无回调的express的中间件
- withCallbackHandler : 处理有回调的express的中间件
这里的回调就是有无next方法, next方法就是进入下一个中间件
/**
* If the middleware function does declare receiving the `next` callback
* assume that it's synchronous and invoke `next` ourselves
*/
function noCallbackHandler(ctx, connectMiddleware, next) {
connectMiddleware(ctx.req, ctx.res)
return next()
}
/**
* The middleware function does include the `next` callback so only resolve
* the Promise when it's called. If it's never called, the middleware stack
* completion will stall
*/
function withCallbackHandler(ctx, connectMiddleware, next) {
return new Promise((resolve, reject) => {
connectMiddleware(ctx.req, ctx.res, err => {
if (err) reject(err)
else resolve(next())
})
})
}
/**
* Returns a Koa middleware function that varies its async logic based on if the
* given middleware function declares at least 3 parameters, i.e. includes
* the `next` callback function
*/
function koaConnect(connectMiddleware) {
const handler = connectMiddleware.length < 3
? noCallbackHandler
: withCallbackHandler
return function koaConnect(ctx, next) {
return handler(ctx, connectMiddleware, next)
}
}
module.exports = koaConnect
koaConnect方法
function koaConnect(connectMiddleware) {
const handler = connectMiddleware.length < 3
? noCallbackHandler
: withCallbackHandler
return function koaConnect(ctx, next) {
return handler(ctx, connectMiddleware, next)
}
}
kaoConnect返回的是一个koa版本的中间件.
connectMiddleware.length是express中间件参数的长度, 如果你这个中间件使用了arguments进行参数解析或者使用了rest参数, 那么这个length本身就准确了.
通过express中间件参数的长度分别调用有回调和无回调的方法.
noCallbackHandler方法
function noCallbackHandler(ctx, connectMiddleware, next) {
connectMiddleware(ctx.req, ctx.res)
return next()
}
直接调用express方法, ctx.req 和 ctx.res作为参数传入.
ctx.req: Node 的 request 对象.
ctx.res: Node 的 Reponse 对象.
这说明express的中间的req 和 res 和koa中间件的ctx.req 和res就是一个玩意.
因为express中间件没有调用next, 所以被调用完毕, 直接调用koa中间件的next
withCallbackHandler方法
function withCallbackHandler(ctx, connectMiddleware, next) {
return new Promise((resolve, reject) => {
connectMiddleware(ctx.req, ctx.res, err => {
if (err) reject(err)
else resolve(next())
})
})
}
返回一个Promise, 因为koa中有 await next()的形式调用, 这就很好的满足了需求.
express中间里面假如有第三个参数next,调用表示进入下一个中间件.
express中间件next调用的时候可以传入Error,
可以参考express error handling
app.get("/", function (req, res, next) {
fs.readFile("/file-does-not-exist", function (err, data) {
if (err) {
next(err); // Pass errors to Express.
}
else {
res.send(data);
}
});
});
回到我们的withCallbackHandler方法
这里express的中间件的next方法即为
err => {
if (err) reject(err)
else resolve(next())
}
当有错误的时候,reject
当没有错误的时候, 调用koa中间件的next, 继续下面的执行.
koa-connect就分析完毕了, 核心就两点
- 通过express中间件的参数长度来区分处理
- 改造express中间件的next方法
koa-connect源码解析的更多相关文章
- Koa源码解析,带你实现一个迷你版的Koa
前言 本文是我在阅读 Koa 源码后,并实现迷你版 Koa 的过程.如果你使用过 Koa 但不知道内部的原理,我想这篇文章应该能够帮助到你,实现一个迷你版的 Koa 不会很难. 本文会循序渐进的解析内 ...
- Netty 源码解析(九): connect 过程和 bind 过程分析
原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 今天是猿灯塔“365篇原创计划”第九篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源 ...
- Koa源码解析
Koa是一款设计优雅的轻量级Node.js框架,它主要提供了一套巧妙的中间件机制与简练的API封装,因此源码阅读起来也十分轻松,不论你从事前端或是后端研发,相信都会有所收获. 目录结构 首先将源码下载 ...
- Koa2 源码解析(1)
Koa2 源码解析 其实本来不想写这个系列文章的,因为Koa本身很精简,一共就4个文件,千十来行代码. 但是因为想写 egg[1] 的源码解析,而egg是基于Koa2的,所以就先写个Koa2的吧,用作 ...
- OKHttp源码解析
http://frodoking.github.io/2015/03/12/android-okhttp/ Android为我们提供了两种HTTP交互的方式:HttpURLConnection 和 A ...
- FileZilla客户端源码解析
FileZilla客户端源码解析 FTP是TCP/IP协议组的协议,有指令通路和数据通路两条通道.一般来说,FTP标准命令TCP端口号是21,Port方式数据传输端口是20. FileZilla作为p ...
- 设置ZooKeeper服务器地址列表源码解析及扩展
设置ZooKeeper服务器地址列表源码解析及扩展 ZooKeeper zooKeeper = new ZooKeeper("192.168.109.130:2181",SESSI ...
- Netty5客户端源码解析
Netty5客户端源码解析 今天来分析下netty5的客户端源码,示例代码如下: import io.netty.bootstrap.Bootstrap; import io.netty.channe ...
- Gin框架源码解析
Gin框架源码解析 Gin框架是golang的一个常用的web框架,最近一个项目中需要使用到它,所以对这个框架进行了学习.gin包非常短小精悍,不过主要包含的路由,中间件,日志都有了.我们可以追着代码 ...
- Android八门神器(一): OkHttp框架源码解析
HTTP是我们交换数据和媒体流的现代应用网络,有效利用HTTP可以使我们节省带宽和更快地加载数据,Square公司开源的OkHttp网络请求是有效率的HTTP客户端.之前的知识面仅限于框架API的调用 ...
随机推荐
- 【Golang 接口自动化01】使用标准库net/http发送Get请求
发送Get请求 使用Golang发送get请求很容易,我们还是使用http://httpbin.org作为服务端来进行演示. package main import ( "bytes&quo ...
- Codeforces D - The Child and Zoo
D - The Child and Zoo 思路: 并查集+贪心 每条边的权值可以用min(a[u],a[v])来表示,然后按边的权值从大到小排序 然后用并查集从大的边开始合并,因为你要合并的这两个联 ...
- Codeforces 894B - Ralph And His Magic Field
894B - Ralph And His Magic Field 思路: 当k为1时,如果n和m奇偶性不同,那么没有答案. 可以证明,在其他情况下有答案,且答案为2^(n-1)*(m-1),因为前n- ...
- 算法笔记--STL中的各种遍历及查找(待增)
算法笔记 map: map<string,int> m; map<string,int>::iterator it;//auto it it = m.begin(); whil ...
- Python string常用函数
2017-07-03 23:26:08 1..replace(self, old, new, count=-1) replace()函数将旧字符串替换为新字符串,最后一个参数count为可选项,表示替 ...
- 12月15日 session:Ruby on Rails Security Guide//从第3节开始没有学习//关于find_by 和where的区别用法思考。
http://guides.rubyonrails.org/security.html#user-management 2.session笔记见13日的随笔. http://www.cnblogs.c ...
- JavaScript 和 React,React用了大量语法糖,让JS编写更方便。
https://reactjs.org/docs/higher-order-components.htmlhttps://codepen.io/gaearon/pen/WooRWa?editors=0 ...
- 转 解决linux下tomcat的shutdown命令杀不死进程
tomcat在windows下可以直接关闭,但是貌似在Linux下有时候shutdown.sh 没有关闭tomcat进程; 现象:在Linux下shutdown.sh ,然后查看tomcat进程发现没 ...
- IP分类
IP: IP分为公有ip和私有ip. 私有ip分为以下5类: 类别 ip范围 子网掩码 A 1.0.0.0------127.255.255.255 255.0.0.0 B 128.0.0.0---1 ...
- HDU-3480 Division (四边形不等式优化DP)
题目大意:将n个数分成m组,将每组的最大值与最小值的平方差加起来,求最小和. 题目分析:先对数排序.定义状态dp(i,j)表示前 j 个数分成 i 组得到的最小和,则状态转移方程为dp(i,j)=mi ...