【nodejs原理源码赏析(2)】KOA中间件的基本运作原理
【摘要】 KOA中间件的基本运作原理
示例代码托管在:http://www.github.com/dashnowords/blogs
在中间件系统的实现上,KOA
中间件通过async/await
来在不同中间件之间交换控制权,工作机制和栈结构非常相似,建议结合《express中间件系统的基本实现》对比学习,两个框架所基于的语法特性有区别(express
使用ES5
的回调风格语法,KOA
使用ES7
的扁平式异步async/await
风格语法),但在框架基本原理上是很类似的,只是中间件写法和遍历机制稍有不同。
一. API层
初始化方法
let middleware = new MiddleWare();
添加中间件函数的方法
//Fn为被添加的中间件,KOA中间件为async函数 middleware.use(Fn);
预处理中间件栈
//将存储于数组中的各个中间件组合为按照“先进后出”原则执行的中间件系统。 middleware.start = middleware.compose();
启动中间件队列
middleware.start(ctx);
二. 核心类的定义
/*
* KOA中间件框架的基本实现
*/class MiddleWare {constructor(){this.queue = []}//添加中间件函数use(fn){this.queue.push(fn);}//合并中间件处理流,是一个高阶函数,调用一次后会生成真正需要的函数。compose(){return function (ctx, next) {let _this= this;let index = -1;return dispatch(0);/*** KOA中间件的工作的步进函数*/function dispatch(i) {index = i;//依次取用数组中添加的中间件函数let fn = i === _this.queue.length ? next : _this.queue[i];if(!fn){return Promise.resolve();}try{/**中间件函数的形式为 async fn(ctx, next),可以看到此处透传了ctx的引用,*同时next是一个延迟执行中间件队列中下一个中间件的函数,也就是说如果在前*一个中间件的函数体中调用 await next(),就会启动下一个中间件,实际执行*的函数是dispatch(i+1)。*/return Promise.resolve(fn(ctx,()=>{return dispatch(i+1);}));}catch(err){return Promise.reject(err);}}}}
}
三. 使用use方法添加中间件
//添加回调函数
middleware.use(async function(ctx, next){console.log('step 001');ctx.info = 'go through middleware1';await next();console.log('step 006');
});middleware.use(async function(ctx, next){console.log('step 002');await next();console.log('step 005');
});middleware.use(async function(ctx, next){console.log('step 003');await next();console.log('step 004');
});
四. 中间件实例
//初始化
let middleware = new MiddleWare();/*
...此处为添加中间件的代码
*/middleware.start = middleware.compose();
五. 查看运行结果
可以看到有错误发生和正常响应时的不同结果:
六. 在服务器端运行
用node
起一个web服务器那真是太随意了~
//启动http服务
http.createServer(function(req, res){console.log(req.url);let info = {};middleware.start(info);res.end(JSON.stringify(info));
}).listen(9527);
看一下效果(访问服务器时自定义消息就可以传至前台了):
作者:大史不说话
【nodejs原理源码赏析(2)】KOA中间件的基本运作原理相关推荐
- 【nodejs原理源码赏析(1)】Express中间件系统的基本实现
一直觉得express的中间件系统这种流式处理非常形象,就好像加工流水线一样,每个环节都在针对同一个产品的不同部分完成自己的工作,最后得到一个成品.今天就来实现一个简易的[中间件队列]. 一. API ...
- 【nodejs原理源码赏析(6)】深度剖析cluster模块源码与node.js多进程(下)
目录 一. 引言 二.server.listen方法 三.cluster._getServer( )方法 四.跨进程通讯工具方法Utils 五.act:queryServer消息 六.轮询调度Roun ...
- 【nodejs原理源码赏析(5)】net模块与通讯的实现
[摘要] Node.js net模块的原理及使用 示例代码托管在:http://www.github.com/dashnowords/blogs 一. net模块简介 net模块是nodejs通讯功能 ...
- 【nodejs原理源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)
[摘要] 集群管理模块cluster浅析 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 概述 cluster模块是node.js中用于实现和管理 ...
- 【nodejs原理源码赏析(9)】用node-ssh实现轻量级自动化部署
[摘要] node脚本实现轻量级自动化部署 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 需求描述 前端工程出包后实现简易的自动化部署. 二. ...
- 【nodejs原理源码赏析(6)】深度剖析cluster模块源码与node.js多进程
示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 文章 ...
- 【nodejs原理源码赏析(4)】深度剖析cluster模块源码与node.js多线程(上)
[摘要] 集群管理模块cluster浅析 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 概述 cluster模块是node.js中用于实现和管理 ...
- 【nodejs原理源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
[摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...
- 【nodejs原理源码赏析(3)】欣赏手术级的原型链加工艺术
[摘要] 学习经典代码中的prototype加工 示例代码托管在:http://www.github.com/dashnowords/blogs 好的代码都差不多,烂的代码却各有各的烂法. 一. 概述 ...
最新文章
- 给网站管理员的建议:创建可利用的、可抓取的网站
- IOS开发之JSON序列化从客户端发送到服务器端
- ArcEngine开发体验(附许可)
- vim中的jk为什么是上下_JK轮胎的完整形式是什么?
- python中set()函数==》创建一个无序不重复的元素集(创将一个集合)
- *第6章 判别分析及R使用
- 【计算机网络】第一部分 概述(1) 数据通信和网络绪论
- 01-unity下载与安装
- python获取12306火车票_Python脚本实现12306火车票查询系统
- 为什么快手不能左右滑了_快手现在为什么不能滑动播放了
- 分布式Zookeeper-基础
- 计算机系统基础实验:二进制拆弹实验
- php fflush失败,php fflush 函数_PHP教程
- 扎拉赞恩 服务器 微信群,《魔兽世界怀旧服》杜隆塔尔扎拉赞恩攻略 任务怎么玩...
- ADDS:检查 AD Domain 的健康和复制状态
- Xamarin.Forms之AbsoluteLayout
- JavaFX+Jfoenix 学习笔记(五)--ContextMenu右键菜单
- SQL—分组数据(GOUP BY)
- 团建游戏---落难月球
- 信息学奥赛一本通:1163:阿克曼(Ackmann)函数