【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原理&源码赏析(5)】net模块与通讯的实现
[摘要] Node.js net模块的原理及使用 示例代码托管在:http://www.github.com/dashnowords/blogs 一. net模块简介 net模块是nodejs通讯功能 ...
- 【nodejs原理&源码赏析(5)】net模块与通讯的实现
目录 一. net模块简介 二. Client-Server的通讯 2.1 server的建立 2.2 Socket的建立 三. IPC通讯 四. 撸一个简易的cluster通讯模型 示例代码托管在: ...
- 【nodejs原理&源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)
[摘要] 集群管理模块cluster浅析 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 概述 cluster模块是node.js中用于实现和管理 ...
- 【nodejs原理&源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)
目录 一. 概述 二. 线程与进程 三. cluster模块源码解析 3.1 起步 3.2 入口 3.3 主进程模块master.js 3.4 子进程模块child.js 四. 小结 示例代码托管在: ...
- 【nodejs原理&源码赏析(3)】欣赏手术级的原型链加工艺术
目录 一. 概述 二. 原型链基础知识 三. Worker类的原型链加工 四. 实例的生成 五. 最后一个问题 六. 一些心得 示例代码托管在:http://www.github.com/dashno ...
- 【nodejs原理&源码赏析(6)】深度剖析cluster模块源码与node.js多进程(下)
[摘要] cluster模块详解 示例代码托管在:http://www.github.com/dashnowords/blogs 阅读本章需要先阅读本系列前两章内容预热一下. 一. 引言 前两篇博文中 ...
- 【nodejs原理&源码赏析(3)】欣赏手术级的原型链加工艺术
[摘要] 学习经典代码中的prototype加工 示例代码托管在:http://www.github.com/dashnowords/blogs 好的代码都差不多,烂的代码却各有各的烂法. 一. 概述 ...
- 【nodejs原理&源码赏析(6)】深度剖析cluster模块源码与node.js多进程(下)
目录 一. 引言 二.server.listen方法 三.cluster._getServer( )方法 四.跨进程通讯工具方法Utils 五.act:queryServer消息 六.轮询调度Roun ...
- KOA中间件的基本运作原理
示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 在中 ...
随机推荐
- vue引入百度地图 --BMap is not defined ,eslint BMap报错
在mounted初始化地图的时候,因为异步问题会导致BMap is not defined,也就是百度的api还没完全引入或者加载完成,就已经进行地图初始化了 解决方法: 1.创建一个map.js e ...
- GitHub + jsDelivr + PicGo + Imagine 打造稳定快速、高效免费图床
GitHub + jsDelivr + PicGo + Imagine 打造稳定快速.高效免费图床 前言 为什么要使用图床呢? 因为在不同平台发布同一篇文章的时候,最一个痛苦的点就是,图片存储问题,各 ...
- Ansibile之playbook初识
一.playbook简介 ansiblie的任务配置文件被称为playbook,俗称“剧本”,每一个剧本(playbook)中都包含了一系列的任务,这每个任务在ansible中又被称为“戏剧”(pla ...
- 部署django
添加uwagi配置文件 在你项目的根目录中创建mysite.xml(名字无所谓),或者创建mysite.ini,输入以下内容: <uwsgi> <socket>127.0.0. ...
- T-SQL Part X: UNION, EXCEPT and INTERSECT
MSDN上关于EXCEPT和INTERSECT的文档.MSDN上关于UNION的文档. 值得注意的是,UNION其实有两种,一种是普通的UNION,另外一种是UNION ALL.加上EXCEPT和IN ...
- Linux 下的这些高效指令,是你快速学习的神器
Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协议.它支持32位 ...
- 第一篇: openJDK源码编译安装--mac版本
1.为什么要编译JDK 想要一探JDK内部的实现机制,最便捷的路径之一就是自己编译一套JDK,通过阅读和跟踪调试JDK源码去了解Java技术体系的原理,虽然门槛高一点,但肯定比阅读各种书籍,文章,博客 ...
- lqb 基础练习 十六进制转十进制
基础练习 十六进制转十进制 时间限制:1.0s 内存限制:512.0MB 问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出. 注:十六进制数中的10~ ...
- 破解网站二维码验证,Java实现,不调用任何平台api接口
package image.images; import java.io.File; import java.io.IOException; import java.io.InputStream; i ...
- vue项目引入自定义.css的样式文件
ES6的引入方式: .vue文件中 css文件引入 <template></template> <style scoped> @import "../as ...