浅谈Express和Koad区别
-
从架构上来说 : express比较全 它内置了很多好用的功能比如router 等等我们不用另外安装,koa则走的是简介路线 他只是包含了核心的功能 甚至在app中连get post都没有 我们需要进行按需求选择安装(从express到koa变得简洁了);
这也符合我们前端的发展路线 大观看过去现在的前端都是在趋于简洁化,比如vue 在vue2中 早期还封装了网络请求等等,vue3中我们后期使用事件总线也是使用第三方库 。
-
从执行顺序上来说(同步) : 在koa中的中间件的执行默认是 顺序执行 这是 **理想 **的状态,每一个中间件在没有异步操作的情况下会等到上一个中间件的结果再执行当前中间件 express也是一样 ;
-
从执行顺序上来说(异步) : 在koa中如果有异步他会自动跳过当前的中间件 往后继续执行 express也是一样不会等待 那么主要 的区别就在这里 ;在koa中的next函数返回的是一个promise 所以我们可以使用async 和await来解决这种异步问题 ;但是在express中的next返回的是一个void;这也是express的缺点 在express中就没有想过 等待异步
Tips1 (koa同步和异步中间件执行解析)😄
同步:
在koa中执行顺序是先调用第一个匹配的中间件 如果该中间件中有调用next就会执行第二个中间件 直到最后一个中间件结束 然后他会进行一个回流 这次回流就是看看next后面的代码是否需要执行如果有需要执行的代码就会执行一下直到第一个中间件
const Koa = require('koa'); const axios = require('axios'); const app = new Koa(); /* 需求:三个中间件依次执行一遍 在第一个中间件中返回结果 */ app.use((ctx, next) => { console.log('Koa Sync Middleware1'); ctx.message = 'a'; next(); ctx.body = ctx.message; }); app.use((ctx, next) => { console.log('Koa Sync Middleware2'); ctx.message += 'b'; next(); }); app.use((ctx, next) => { console.log('Koa Sync Middleware3'); ctx.message += 'c'; next(); }); app.listen(8000, () => { console.log('Koa同步服务器启动成功~'); });
AipFox返回结果:
abc
控制台返回结果:
Koa Sync Middleware1 Koa Sync Middleware2 Koa Sync Middleware3
异步:
const Koa = require('koa'); const axios = require('axios'); const app = new Koa(); /* 需求:三个中间件依次执行一遍 在第一个中间件中返回结果 */ app.use((ctx, next) => { console.log('Koa Async Middleware1'); ctx.message = 'a'; next(); ctx.body = ctx.message; }); app.use((ctx, next) => { console.log('Koa Async Middleware2'); ctx.message += 'b'; next(); }); app.use(async (ctx, next) => { console.log('Koa Async Middleware3'); const res = await axios.get('http://localhost:8080'); ctx.message += 'c' + res; next(); }); app.listen(8000, () => { console.log('Koa同步服务器启动成功~'); });
AipFox返回结果:
abc
控制台返回结果:
Koa Async Middleware1 Koa Async Middleware2 Koa Async Middleware3
由此可见在koa中 异步的中间件可以执行但是他不会等待异步的结果就自动回流了,如果我们就需要等待结果呢?
koa异步结果等待解决方案:
const Koa = require('koa'); const axios = require('axios'); const app = new Koa(); /* 需求:三个中间件依次执行一遍 在第一个中间件中返回结果 */ app.use(async (ctx, next) => { console.log('Koa Async Middleware1'); ctx.message = 'a'; await next(); ctx.body = ctx.message; }); app.use(async (ctx, next) => { console.log('Koa Async Middleware2'); ctx.message += 'b'; await next(); }); app.use(async (ctx, next) => { console.log('Koa Async Middleware3'); const res = await axios.get('http://localhost:8080'); ctx.message += 'c' + res.data; next(); }); app.listen(8000, () => { console.log('Koa异步服务器启动成功~'); });
AipFox返回结果:
abcAsync Result
控制台返回结果:
Koa Async Middleware1 Koa Async Middleware2 Koa Async Middleware3
我们只需要给每个中间件的next方法加上一个await,这样在回流的时候koa就会等待该中间件的执行结果再回流
这时候即使该next下面还有代码 他还是会等待 等待该next的结果后在执行当前的next下面的代码。
中间件 async 由上到下---------先执行 await next() ---等待结果 回流中-----------上级next有结果了再执行这里
Tips2 (express同步和异步中间件执行解析)😄
同步:
就express中的同步代码而言他是和koa同步代码执行流程是一样的都是会回流执行next下面的代码
代码:
const express = require('express'); const app = express(); app.use((req, res, next) => { req.msg = 'a'; console.log('Express Sync Middleware1'); next(); res.json(req.msg); }); app.use((req, res, next) => { req.msg += 'b'; console.log('Express Sync Middleware2'); next(); }); app.use((req, res, next) => { req.msg += 'c'; console.log('Express Sync Middleware3'); next(); }); app.listen(8000, () => { console.log('Express同步服务器启动成功'); });
AipFox返回结果:
"abc"
控制台返回结果:
Express Sync Middleware1 Express Sync Middleware2 Express Sync Middleware3
异步:
如果是异步的话我们能不能像koa中的异步一样等待结果呢? 他不会等待 在最开始设计express的时候就没有想过这种需求 当然也有解决方案 但是很难对于我来说🐨 我的解决方案是在第三个中间件中返回结果
const express = require('express'); const app = express(); const axios = require('axios'); app.use((req, res, next) => { req.msg = 'a'; console.log('Express Async Middleware1'); next(); }); app.use((req, res, next) => { req.msg += 'b'; console.log('Express Async Middleware2'); next(); }); app.use(async (req, res, next) => { console.log('Express Async Middleware3'); const Result = await axios.get('http://localhost:8080'); req.msg += 'c' + Result.data; next(); res.json(req.msg);----返回结果 }); app.listen(8000, () => { console.log('Express同步服务器启动成功'); });
AipFox返回结果:
"abcAsync Result"
控制台返回结果:
Express Async Middleware1 Express Async Middleware2 Express Async Middleware3
你在express中只要有异步你就回不去了 你不能回流了 你在第一个中间件中拿不到第三个异步结果
这也是TJ设计koa的初衷
附加:
洋葱模型: koa中的异步和同步 express中的同步 都是符合洋葱模型概念的 就是回流的概念 洋葱模型说的也就是回流。
由外而内 再由内而外