77 # koa 中间件的应用

调用 next() 表示执行下一个中间件

javascript 复制代码
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

添加异步等待

javascript 复制代码
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 否则不存在等待效果

javascript 复制代码
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():

  1. 可以把多个模块通过 next 方法来链接起来
  2. 可以决定是否向下执行(可以用来实现后台的权限)
  3. 可以封装一些方法,在中间件中,封装向下执行

实现中间件计时器

javascript 复制代码
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);
相关推荐
摘星编程3 小时前
深入理解责任链模式:从HTTP中间件到异常处理的实战应用
http·设计模式·中间件·责任链模式·实战应用
~山有木兮2 天前
LiteHub中间件之限流实现
网络·http·中间件
fo安方2 天前
运维的利器–监控–zabbix–第三步:配置zabbix–中间件–Tomcat–步骤+验证
运维·中间件·zabbix
Code季风2 天前
Gin 中间件详解与实践
学习·中间件·golang·go·gin
一只程序汪3 天前
【如何实现分布式压测中间件】
分布式·中间件
William一直在路上3 天前
主流分布式中间件及其选型
分布式·中间件
listhi52013 天前
深入浅出Node.js中间件机制
中间件·node.js
骆驼Lara13 天前
前端跨域解决方案(7):Node中间件
前端·javascript·中间件
无糖钨龙茶14 天前
理解后端开发中的中间件(以gin框架为例)
中间件·go·gin