首先,我们手动模拟一下发送网络请求的代码:
//函数主体
const request = (arg, cb) => {
setTimeout(() => {
console.log(arg);
cb(arg + 1);
}, 300);
};
//产生回调地狱,阅读性差
request(1, (arg1) => {
request(arg1, (arg2) => {
request(arg2, (arg3) => {
request(arg3, (arg4) => {
console.log("arg5:", arg4);
});
});
});
});
输出结果为:
接下来我们用promise实现一下
const request = (arg) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(arg);
resolve(arg + 1);
}, 300);
});
};//用promise重构的代码
request(1)
.then((res1) => request(res1))
.then((res2) => request(res2))
.then((res3) => request(res3))
.then((res4) => console.log("arg5:", res4));
输出结果为:
使用async函数:
const request = (arg) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(arg);
resolve(arg + 1);
}, 300);
});
};
const fn = async () => {
const res1 = await request(1);
const res2 = await request(res1);
const res3 = await request(res2);
const res4 = await request(res3);
console.log("arg5:", res4);
};
fn();
输出结果为:
对比promise和async、await的实现可以得出,await后面接一个promise对象,const res1 = await request(1);中res1的值是promise的then((res)=>{})中的res,即resolve中的resolve(arg)中的arg。 结合以上,在koa框架中使用例子:
const Koa = require("koa");
const app = new Koa();
//cts context
// 通过app.use 注册中间件
// 中间件本质就是函数
// context 上下文 当前请求的相关信息都在里面
app.use(async (ctx, next) => {
console.log(1);
await next()
console.log(4);
})
app.use(async (ctx, next) => {
console.log(2);
await next();
console.log(5);
})
app.use(async (ctx, next) => {
console.log(3)
await next()
console.log(6);
})
// 开启一个http服务,端口为3000,在浏览器打开localhost:3000
// 接收http 请求 并做处理,处理完后响应
app.listen(3000, () => {
console.log(`启动成功`);
});
结果
从结果不难推出中间件的执行顺序。