FrankKai.github.io
FrankKai.github.io copied to clipboard
Node框架那些事儿
nodejs框架,express,koa,egg
- express和koa的区别
- egg和koa的区别
- koa洋葱模型中间件实现原理
express和koa的区别
1.中间件实现方式不同 express是callback方式,会有callback hell问题;koa为洋葱模型,基于promise和async实现 2.express只有request和response对象,而koa有context对象,类似traceId,可以贯穿上下文 3.koa采用async的方式实现,所以可以以同步方式写异步逻辑,代码逻辑更加直观 4.koa异常处理更加便捷
egg和koa的区别
1.egg基于koa实现 2.egg扩展,可以扩展application,context,request,response原型对象 3.egg插件,某一类型的中间件集合,与webpack 插件类似,插拔式使用某一个功能,方便又快捷
koa洋葱模型中间件实现原理
const middleware = []
let mw1 = async function (ctx, next) {
console.log("next前,第一个中间件")
next()
console.log("next后,第一个中间件")
}
let mw2 = async function (ctx, next) {
console.log("next前,第二个中间件")
next()
console.log("next后,第二个中间件")
}
let mw3 = async function (ctx, next) {
console.log("第三个中间件,没有next了")
}
function use(mw) {
middleware.push(mw);
}
function compose(middleware) {
return (ctx, next) => {
return dispatch(0);
function dispatch(i) {
const fn = middleware[i];
if (!fn) return;
return fn(ctx, dispatch.bind(null, i+1));
}
}
}
use(mw1);
use(mw2);
use(mw3);
const fn = compose(middleware);
fn();
async promise版
const middleware = []
let mw1 = async function (ctx, next) {
console.log("next前,第一个中间件")
await next()
console.log("next后,第一个中间件")
}
let mw2 = async function (ctx, next) {
console.log("next前,第二个中间件")
await next()
console.log("next后,第二个中间件")
}
let mw3 = async function (ctx, next) {
console.log("第三个中间件,没有next了")
}
function use(mw) {
middleware.push(mw);
}
function compose(middleware) {
return (ctx, next) => {
return dispatch(0);
function dispatch(i) {
const fn = middleware[i];
if (!fn) return Promise.resolve();
return Promise.resolve(fn(ctx, dispatch.bind(null, i+1)));
}
}
}
use(mw1);
use(mw2);
use(mw3);
const fn = compose(middleware);
fn();
// next前,第一个中间件
// next前,第二个中间件
// 第三个中间件,没有next了
// next后,第二个中间件
// next后,第一个中间件
Koa中间件koa-compose解决了什么问题?
解决了callback回调地狱问题以及请求执行完后再执行响应的问题。 通过next()来代替下一个中间件,使得每个中间件代码封闭在各个next中。
什么时候为返回执行response的时机?
i+1不断累加,指向了middleware[middleware.length],即超出数据边界时,当fn为空时,开始执行返回逻辑。
if(!fn) return;
当前中间件执行是如何获取下一个中间件next的?
通过bind生成一个全新的middle。
dispatch.bind(null, i+1)
```