koa之koa-compose
介绍
koa-compose是koa用到的类库,用于koa中间件合并执行,compose是将多个函数合并成一个函数(eg: a() + b() +c()=> c(b(c()))),主要使用Promise/Async、递归调用实现。整个代码包括注释不到50行,非常精巧。
安装
npm install koa-compose
用法
compose([fun a{}, fun b{}, fun c{}, …])
例子
const compose=require('koa-compose')async function test(){const midFuns = []midFuns.push(async (context, next) => {console.log(1)await next()console.log(6)})midFuns.push(async (context, next) => {console.log(2)await next()console.log(5)})midFuns.push(async (context, next) => {console.log(3)await next()console.log(4)})console.log(midFuns)await compose(midFuns)({})
}
test()
next 表示调用下一个midFun,打印结果如下:
1
2
3
4
5
6
源码
'use strict'/*** Expose compositor.*/module.exports = compose/*** Compose `middleware` returning* a fully valid middleware comprised* of all those which are passed.** @param {Array} middleware* @return {Function}* @api public*/function compose (middleware) {if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')for (const fn of middleware) {if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')}/*** @param {Object} context* @return {Promise}* @api public*/return function (context, next) {// last called middleware #let index = -1return dispatch(0)function dispatch (i) {if (i <= index) return Promise.reject(new Error('next() called multiple times'))index = ilet fn = middleware[i]if (i === middleware.length) fn = nextif (!fn) return Promise.resolve()try {return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));} catch (err) {return Promise.reject(err)}}}
}
它返回的是一个已经合并好的函数,根据传入的函数递归调用dispatch。
- 首先调用dispatch(0),if (i <= index) 也就是 0<=-1不成立,继续往下走,这里主要避免在一个中间件内多次调用next
- 继续下一步 index = i,此时index=0了
- let fn = middleware[i] 获取到第一个中间件fn
- if (i === middleware.length) fn = next 这里的next为undefined
- 接下来就是最最核心的代码了,这里调用fn(也就是我们的中间件函数),并传入了两个参数一个是原来的context,一个是dispatch函数(递归调用,参数i值加1)
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
dispatch.bind(null, i + 1) 返回一个新的dispatch函数,下面一个小例子,展示bind的作用
function multiply (x, y, z) {return x * y * z; } var double = multiply.bind(null, 2); //Outputs: 24 console.log(double(3, 4));
我们将前面的例子代码大致转换一下,看看最后是啥样
Promise.resolve(function(context){ //第一个中间件console.log(1)await Promise.resolve(function(context){ //第二个中间件 => await next()console.log(2)await Promise(function(context){ //第三个中间件 => await next()console.log(3)// await next() 最后一个next ,不会再调用其他中间件 直接Promise.resolve()console.log(4)}());console.log(5)}())console.log(6)
}());
koa之koa-compose相关推荐
- koa compose源码阅读
众所周知,在函数式编程中,compose是将多个函数合并成一个函数(形如: g() + h() => g(h())),koa-compose则是将 koa/koa-router 各个中间件合并执 ...
- 【koa系列】koa洋葱模型及其compose原理解析
什么是洋葱模型 先来看一个 demo const Koa = require('koa'); const app = new Koa();// 中间件1 app.use((ctx, next) =&g ...
- koa源码阅读之koa-compose/application.js
koa源码阅读之koa-compose/application.js koa-Compose 为了理解方便特地把注释也粘进来 //这英语.我也来翻译一波 //大概就是把所有的中间件组合返回一个完整大块 ...
- koa 接口返回数据_一文搞定 Koa 中间件实现原理
Koa是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小.更富有表现力.更健壮的基石. 通过利用 async 函数, Koa ...
- 第四代Express框架koa简介
文章目录 简介 koa和express koa使用介绍 中间件的级联关系 koa的构造函数 启动http server 自定义中间件 异常处理 简介 熟悉Spring MVC的朋友应该都清楚Sprin ...
- 洋葱模型php,理解Koa洋葱模型
中间件特性 | | | middleware 1 | | | | +-----------------------------------------------------------+ | | | ...
- Koa 中间件的执行
Node.js 中请求的处理 讨论 Koa 中间件前,先看原生 Node.js 中是如何创建 server 和处理请求的. node_server.js const http = require(&q ...
- nodejs express use 传值_再也不怕面试官问你express和koa的区别了
前言 用了那么多年的express.js,终于有时间来深入学习express,然后顺便再和koa2的实现方式对比一下. 老实说,还没看express.js源码之前,一直觉得express.js还是很不 ...
- 一步步实现koa核心代码
导语:实现简单的koa核心代码,便于理解koa原理.顺便学习koa代码的那些骚操作 简单分析koa 创建一个 http 服务,只绑一个中间件.创建 index.js /** index.js */ c ...
- Koa在实际的业务场景中,路由如何做分割?【文末留言送书】
大家好,我是若川.文末留言送书,具体规则文末说明.另外为了鼓励大家多写源码共读笔记,我会在写了5次及以上笔记的作者群里也抽奖送这本书.以后也会有更多福利倾斜. 导读:Koa是一个Node框架,在Nod ...
最新文章
- 西湖大学最年轻博导来了丨93年出生的他,想创造属于中国的“追光”纪录
- Boosting GDBT
- 剑指Offer 64 求1+2+...+n
- 【从 0 开始机器学习】逻辑回归识别手写字符!
- 5、利用控件TVCLZip和TIdFTP压缩文件并上传到FTP的线程单元pas 改进版
- 永磁同步电机学习(一)
- 客户需求分析工具-$APPEALS
- 固态硬盘(SSD)——NAND闪存芯片(颗粒)QLC、SLC、MLC、TLC
- MATLAB机器人工具箱2-机器人模型建立
- 【K8S】K8s部署Metrics-Server服务
- Android 状态栏常规操作(状态栏显示,状态栏颜色,沉浸式状态栏)
- 检测站营销系列文章:机动车检测站如何做精益营销?
- 《三国演义》十大不义之人
- 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡是报到3的人退出圈子,问最后留下来的是原来的第几位(指针方法处理)。——C语言
- 小型音乐播放器插件APlayer.js的简单使用例子 1
- 【linux系统安装jdk11】
- 为自动驾驶carla配置车流量
- Lodop常用属性和方法字典(转)
- java必备十大技术网站
- case when和COALESCE