跳到主要内容

机制

2023年05月31日
柏拉文
越努力,越幸运

一、同步


1.1 同步拼接

function compose(req, res, middleware) {
const next = () => {
const fn = middleware.shift();
if (fn) {
fn(req, res, next);
}
};
next();
}

function middleware1(req, res, next) {
req.message = "aaa";
next();
console.log(req.message);
}
function middleware2(req, res, next) {
req.message += "bbb";
next();
}
function middleware3(req, res, next) {
req.message += "ccc";
}

const req = {};
const res = {};
const middleware = [middleware1, middleware2, middleware3];
compose(req, res, middleware);

结果: aaabbbccc

分析: 其实expresskoa同步实现没有什么区别,都是从上往下执行,当执行到next的时候,会将控制权交给下一个中间件,直到下一个中间件不再执行 next() 后,将会沿路折返,将控制权依次交还给前一个中间件,当交还到第一个中间件res.end时候,req.message里面就为aaabbbccc

二、异步


2.1 异步拼接

function compose(req, res, middleware) {
const next = () => {
const fn = middleware.shift();
if (fn) {
fn(req, res, next);
}
};
next();
}

async function middleware1(req, res, next) {
req.message = "aaa";
await next();
console.log(req.message);
}
async function middleware2(req, res, next) {
req.message += "bbb";
await next();
}

function promiseFun() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("ccc");
}, 3000);
});
}
async function middleware3(req, res, next) {
const result = await promiseFun();
req.message += result;
}

const req = {};
const res = {};
const middleware = [middleware1, middleware2, middleware3];
compose(req, res, middleware);

结果: aaabbb

分析: 在expressnext内部的操作都是同步的,不管下一个中间件是否有异步操作,所以加上await也没有意义