Koa与Express的区别

mac2024-04-16  42

Koa2

基于node的一个web开发框架,利用co作为底层运行框架,利用Generator的特性,实现“无回调”的异步处理; ES7; 更小、更富有表现力、更健壮的基石; 利用async函数、Koa丢弃回调函数,增强错误处理; 很小的体积,因为没有捆绑任何中间件; 类似堆栈的方式组织和执行; 低级中间件层中提供高级“语法糖”,提高了互操性、稳健性;

Express

Node的基础框架,基础Connect中间件,自身封装了路由、视图处理等功能; 线性逻辑,路由和中间件完美融合,清晰明了; 弊端是callback回调方式,不可组合、异常不可捕获; ES5; connect的执行流程: connect的中间件模型是线性的,即一个一个往下执行;

Handler的处理

Express普通回调函数,在同一线程上完成当前进程的所有Http请求; Koa利用Generator Function作为响应器,co作为底层运行框架,利用Generator特性,实现“协程响应”;

路由

Express的路由是自身集成的; Koa的需要引入中间件Koa-router; (视图也是)

启动方式

koa采用new Koa(),express采用传统的函数形式function;

回调

Koa没有回调,express有回调;

Http Request

koa1使用this取代Express的req、res;

Context

Koa新增了一个Context对象,用来代替Express的Request和Response,作为请求的上下文对象。 还有Node原生提供的req、res、socket等对象;

生命周期

Express的生命周期不确定: express内部执行异步函数,不能确定什么时候执行完; Koa的确定: koa是基于await/async,在执行下一步操作的时候,必须等待前端await执行完; const express = require('express'); const app = express(); app.use((req, res, next) => { console.log(1); // 1 next(); // 2 console.log(2); // 5 }); app.use((req, res, next) => { console.log(3); // 3 new Promise((resolve => { // 4 setTimeout(resolve, 300); })).then(() => { next(); // 6 console.log(4); // 8 }); }); app.use(function(req, res) {// 7 res.send('Hello World'); }) app.listen(3000) // 1 3 2 4 const Koa = require('koa'); const app = new Koa(); app.use(async (ctx, next) => { console.log(1); await next(); console.log(2); }); app.use(async (ctx, next) => { console.log(3); await new Promise(((resolve) => { setTimeout(resolve, 300); })); await next(); console.log(4); }); app.use(async (ctx, next) => { ctx.body = 'Hello World'; }); app.listen(3000); // 1 3 4 2

异步流程

Express采用callback来处理异步(ES5); Koa1采用generator(ES6); Koa2采用async/await(ES7);

错误处理

Express使用callback捕获异常,深层次的异常捕获不了; Koa使用try catch,很好的解决异常捕获;

中间件

koa2的中间件: 通过async await实现的,中间件执行的顺序是“洋葱圈”模型。 中间件之间通过next函数联系,当一个中间件调用next()后,会将控制权交给下一个中间件,直到下一个中间件不再执行next()后,会沿路返回,将控制权交给前一个中间件。 const Koa = require('koa'); const app = new Koa(); // logger app.use(async (ctx, next) => { console.log('1 - 开始') await next(); const rt = ctx.response.get('X-Response-Time'); console.log('1 - 结束') }); // x-response-time app.use(async (ctx, next) => { console.log('2 - 开始') const start = Date.now(); await next(); const ms = Date.now() - start; ctx.set('X-Response-Time', `${ms}ms`); console.log('2 - 结束') }); // response app.use(async ctx => { console.log('3 - 开始') ctx.body = 'Hello World'; console.log('3 - 结束') }); app.listen(3000); /** 1 - 开始 2 - 开始 3 - 开始 3 - 结束 2 - 结束 1 - 结束 */ Express中间件: 一个接一个顺序执行,response响应写在最后一个中间件中。 特点: app.use用来注册中间件; 遇到http请求,根据path和method判断触发哪些中间件; 实现next机制,即上一个中间件会通过next触发下一个中间件; const express = require('express') const app = express() app.use((req, res, next) => { console.log('1 - 开始') setTimeout(() => { next() }, 0) console.log('1 - 结束') }) app.use((req, res, next) => { console.log('2 - 开始') setTimeout(() => { next() }, 0) console.log('2 - 结束') }) app.use('/api', (req, res, next) => { console.log('3 - 开始') res.json({ code: 0 }) console.log('3 - 结束') }) app.listen(3000, () => { console.log('server is running on port 3000') }) /** 1 - 开始 1 - 结束 2 - 开始 2 - 结束 3 - 开始 3 - 结束 */
最新回复(0)