Koa框架和Express框架是Node生态圈比较流行的Node Web框架,能够利用这两个框架快速建立web应用。那koa和express这两个框架有什么区别呢?
1、框架体量:Express框架集成了路由、静态文件功能模块,而Koa框架只提供了web服务,所以Koa相对于Express更轻量级;
实现功能点:基本的路由、静态文件功能的Web服务
//Koa版本:利用Koa框架实现路由、静态文件、web服务需要额外引入第三方依赖,Koa框架本身只提供了web服务
const Koa = require("koa");
const Router = require("koa-router"); //引入路由
const Static = require("koa-static"); //引入静态文件服务
const app = new Koa();
const router = new Router();
router.get("/testApi",async (ctx,next)=>{
const response = ctx.response;
response.set("Content-Type","text/html;charset=utf-8");
response.body = "/testApi接口测试成功"
;
});
//注入中间件
app.use(router.routes());
app.use(router.allowedMethods());
app.use(Static("public"));
const PORT = 3000;
const HOST = "localhost"
app.listen(PORT,HOST,function(){
console.log(`http://${
HOST}:${
PORT} 服务启动成功`);
});
//Express版本:利用Express框架实现路由、静态文件、web服务,不需要额外引入第三方,Express本身集成
const Express = require("express");
const app = Express();
const router = Express.Router();
router.get("/testApi",(req,res,next)=>{
res.send(`/testApi服务启动成功!
`)
});
app.use(Express.static("public"));
app.use(router);
const PORT = 3000;
const HOST = "localhost"
app.listen(PORT,HOST,function(){
console.log(`http://${
HOST}:${
PORT} 服务启动成功`);
});
2、 中间件机制:这两种框架都使用了中间件机制实现web应用功能增强,源码中都是通过middleware数组存储中间件功能函数,同时根据洋葱模型机制实现中间件功能触发;
洋葱模型:该模型机制主要为了实现功能增强,在核心代码前后实现相应的功能增强,类似于Aop面向切面编程(@Aroud环绕通知),例如日志记录、报错处理等增强功能;洋葱模型设计图如下:
Express版本:Express中间件执行机制也是洋葱模型;但是由于Express框架对HTTP异步请求采用回调方式处理,不会等待Promise执行完成,所以有时候洋葱模型执行中间并不是那么可靠;例如在如下代码,添加静态文件功能,就会出现不符合洋葱模型的运行方式;
const Express = require("express");
const app = Express();
const router = Express.Router();
router.get("/testApi",(req,res,next)=>{
console.log("/testApi开始访问");
res.send1(`/testApi服务启动成功!
`)
});
function MiddleWareA(req,res,next){
console.log("请求开始日志");
next();
console.log("请求结束日志");
}
function MiddleWareB(req,res,next){
console.log("报错开始日志");
next();
console.log("报错结束日志")
}
app.use(MiddleWareA);
app.use(MiddleWareB);
//app.use(Express.static("public")); //先注释可以看到洋葱模型运行方式
app.use(router);
const PORT = 3000;
const HOST = "localhost"
app.listen(PORT,HOST,function(){
console.log(`http://${
HOST}:${
PORT} 服务启动成功`);
});
(正常版本)
(非正常版本)
Koa版本:Koa中间件执行机制严格按照洋葱模型;由于Koa框架利用async/await语法等待Promise执行完成,如果不采用该语法定义中间件函数,也会出现Express的情况,同时Koa web路由服务无法访问;
const Koa = require("koa");
const Router = require("koa-router"); //引入路由
const Static = require("koa-static"); //引入静态文件服务
const app = new Koa();
const router = new Router();
router.get("/testApi",async (ctx,next)=>{
const response = ctx.response;
console.log("/testApi接口开始访问");
response.set("Content-Type","text/html;charset=utf-8");
response.body = "/testApi接口测试成功"
;
});
async function MiddleWareA(ctx,next){
console.log("请求开始日志");
await next();
console.log("请求结束日志");
}
async function MiddleWareB(ctx,next){
console.log("报错开始日志");
await next();
console.log("报错结束日志")
}
//注入中间件
app.use(MiddleWareA);
app.use(MiddleWareB);
app.use(router.routes());
app.use(router.allowedMethods());
app.use(Static("public"));
const PORT = 3000;
const HOST = "localhost"
app.listen(PORT,HOST,function(){
console.log(`http://${
HOST}:${
PORT} 服务启动成功`);
});
3、 异步处理方式:Express框架采用Callback回调函数的方式处理异步功能,它不会等到Promise执行完成;而Koa2框架采用async/await语法特性处理异步功能,可以通过该语法可以等到Promise执行完成;
4、 报错处理机制:Express对报错处理不太友好,如果控制器(路由函数)中出现错误代码,Express直接抛出报错,无法通过try,catch语法进行拦截处理;Koa框架可以定义报错中间件,对控制器出现的报错进行统一处理拦截;
4、 中间件对响应对象的处理:Koa框架能够在中间件中直接修改Response响应对象,而Express框架在中间件中不能修改Response响应对象,如果修改会产生报错信息;报错信息如下:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:533:11)
at ServerResponse.header (E:\koa-pro\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (E:\koa-pro\node_modules\express\lib\response.js:170:12)
at MiddleWareB (E:\koa-pro\expresspro.js:19:9)
at Layer.handle [as handle_request] (E:\koa-pro\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (E:\koa-pro\node_modules\express\lib\router\index.js:317:13)
at E:\koa-pro\node_modules\express\lib\router\index.js:284:7
at Function.process_params (E:\koa-pro\node_modules\express\lib\router\index.js:335:12)
at next (E:\koa-pro\node_modules\express\lib\router\index.js:275:10)
at MiddleWareA (E:\koa-pro\expresspro.js:12:5)