koa2采用async和await来处理异步,koa2实例的use函数的参数都是中间件。
先来看一个koa2的核心小demo
const arr = [
async (next) => {
console.log(1);
await next();
console.log(2);
},
async (next) => {
console.log(3);
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve(
console.log(4)
);
}, 1000);
});
await next();
console.log(5);
},
async (next) => {
console.log(6);
},
async (next) => {
console.log(7);
await next();
console.log(8);
},
async (next) => {
console.log(9);
}
];
function fun(arr) {
function dispose(index) {
const currentFun = arr[index];
const next = dispose.bind(null, index + 1);
return currentFun(next);
}
dispose(0);
}
fun(arr);
code开始 (新建一个ware.js文件)
const http = require('http');
const urlParser = require("url");
class Middleware {
constructor() {
this.wares = [];
};
use(fun) {
this.wares.push(fun);
return this;
};
handleMiddleware(wareList) {
return function (ctx) {
function dispose(index) {
const currentFun = wareList[index];
try {
return Promise.resolve(
currentFun(ctx, dispose.bind(null, index + 1))
);
} catch (e) {
return Promise.reject(e);
}
}
dispose(0);
}
};
createContext(req, res) {
const {method, url} = req;
const {query} = urlParser.parse(url, true);
return {
method, url, query,
res
};
}
serverHandle() {
return (req, res) => {
const fn = this.handleMiddleware(this.wares);
const ctx = this.createContext(req, res);
fn(ctx);
}
};
listen(...args) {
const app = http.createServer(this.serverHandle());
app.listen(...args);
};
}
module.exports = Middleware;
测试 (同一目录下新建一个demo.js文件)
const Demo = require("./ware");
const app = new Demo();
app.use(async (ctx, next) => {
await next();
console.log(`${ctx.method} ${ctx.url}`);
});
app.use(async ctx => {
ctx.res.end("hello world")
});
app.listen(5000, () => {
console.log("http://localhost:5000");
});
> cmd运行 node demo.js 浏览器访问 http://localhost:5000 => hello world。