讲一讲koa2中简单的发布订阅,以及next异步等待
const http = require('http')
let list = []
let ctx = {}
class Koa {
use (fn) {
list.push(fn) //添加订阅者,即每个use()当中的函数订阅了next
}
listen () {
http.createServer((req, res) => {
const ctx = this.createContext(req, res) //创建上下文(源码当中的上下文指向没这么简单)
const fn = this.middleware(ctx) //中间件原理
fn.then(() => {
res.end(ctx.body)
})
}).listen(...arguments)
}
middleware (ctx) {
function dispatch(index) {
if(index === list.length) return
let match = list[index]
return Promise.resolve(match(ctx, async () => {
return dispatch(++index) //当next执行后继续发布,直到index === list.length
}))
}
return dispatch(0) //添加发布者dispatch,必须返回promise,以实现洋葱圈模型
}
createContext (req, res) {
ctx.request = ctx.req = req
ctx.response = ctx.res = res
return ctx
}
}
module.exports = Koa