A Koa application is an object containing an array of middleware functions which are composed and executed in a stack-like manner upon request. Koa is similar to many other middleware systems that you may have encountered such as Ruby's Rack, Connect, and so on - however a key design decision was made to provide high level "sugar" at the otherwise low-level middleware layer. This improves interoperability, robustness, and makes writing middleware much more enjoyable.
Koa 在2017-02-25 發(fā)布了2.0 版本,詳情請(qǐng)參照git hub 上history.md
1.0 與2.0 版本關(guān)于中間件的異同
1.0 版本是通過(guò)組合不同的 generator,可以免除重復(fù)繁瑣的回調(diào)函數(shù)嵌套,并極大地提升錯(cuò)誤處理的效率。
2.0版本Koa放棄了generator,采用Async 函數(shù)實(shí)現(xiàn)組件數(shù)組瀑布流式(Cascading)的開發(fā)模式。
先來(lái)看看Koa 2.0 版本Hello word的demo,
const Koa = require('koa');
const app = new Koa();
app.use(ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
Koa中間件的方式
Common function
/* Middleware normally takes two parameters (ctx, next), ctx is the context for one request,
next is a function that is invoked to execute the downstream middleware.
It returns a Promise with a then function for running code after completion. */
app.use((ctx, next) => {
const start = new Date();
return next().then(() => {
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
});
Async function
app.use(async (ctx, next) => {
const start = new Date();
await next();
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
async與common function 的區(qū)別主要在于語(yǔ)法糖面前是否存在async,如果需要同步的執(zhí)行中間件或是函數(shù),只需要在中間件或函數(shù)前加關(guān)鍵字await。
// 同步執(zhí)行中間件
app.use(async (ctx, next) => { await next(); });
Koa Cascading 中間件值的傳遞
Middleware1 中間件中的函數(shù)next()返回的是一個(gè)promise 對(duì)像
const Koa = require('koa');
const app = new Koa();
//Middleware 1
app.use(async function (ctx, next) {
console.log("1.1")
await next().then(function (data) {
console.log(data) // "Spursyy"
}).catch(function (err) {
console.log(err)
});
console.log("1.2")
})
//Middleware 2
app.use(async function (ctx, next) {
return new Promise (function (resolve, reject) {
resolve("Spursyy")
})
})
app.listen(3000);
console.log("port 3000 was start!")