调用 next()
表示执行下一个中间件
const Koa = require("koa"); const app = new Koa(); app.use(async (ctx, next) => { console.log(1); next(); console.log(2); }); app.use(async (ctx, next) => { console.log(3); next(); console.log(4); }); app.use(async (ctx, next) => { console.log(5); next(); console.log(6); }); app.listen(3000);
洋葱模型:
输出:135642
添加异步等待
const Koa = require("koa"); const app = new Koa(); const log = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log("kaimo313"); resolve(); }, 3000); }); }; app.use(async (ctx, next) => { console.log(1); next(); console.log(2); }); app.use(async (ctx, next) => { console.log(3); await log(); next(); console.log(4); }); app.use(async (ctx, next) => { console.log(5); next(); console.log(6); }); app.listen(3000);
输出:132 kaimo313 564
koa 中要求每个 next 方法前面都必须增加 await 否则不存在等待效果
const Koa = require("koa"); const app = new Koa(); const log = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log("kaimo313"); resolve(); }, 3000); }); }; app.use(async (ctx, next) => { console.log(1); next(); console.log(2); ctx.body = "hello 1"; }); app.use(async (ctx, next) => { console.log(3); await log(); ctx.body = "hello 2"; next(); console.log(4); }); app.use(async (ctx, next) => { console.log(5); ctx.body = "hello 3"; next(); console.log(6); }); app.listen(3000);
会取中间件第一个执行完的结果
koa 的中间件原理:会将所有的中间件组合成一个大的 promise,当这个 promise 执行完毕后,会采用当前的 ctx.body
进行结果的响应(next 前面必须要有 await 或者 return 否则执行顺序可能达不到预期)
如果都是同步执行,加不加 await 都无所谓,由于不知道后续是否有异步逻辑,写的时候都要加上 await
next():
- 可以把多个模块通过 next 方法来链接起来
- 可以决定是否向下执行(可以用来实现后台的权限)
- 可以封装一些方法,在中间件中,封装向下执行
实现中间件计时器
const Koa = require("koa"); const app = new Koa(); const log = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log("kaimo313"); resolve(); }, 3000); }); }; app.use(async (ctx, next) => { console.time("kaimo"); await next(); ctx.body = "hello 1"; console.timeEnd("kaimo"); }); app.use(async (ctx, next) => { await log(); ctx.body = "hello 2"; return next(); }); app.use(async (ctx, next) => { ctx.body = "hello 3"; return next(); }); app.listen(3000);