express / koa 中间件模型的实现
AwesomeDevin opened this issue · comments
Devin Deng commented
express - 串联模型
koa - 洋葱模型(加入promsie + async/await 异步机制即可)
const http = require('http')
function compose(middlewareList) {
return function (ctx) {
function next (i) {
const fn = middlewareList[i]
if (!fn) {
return Promise.resolve()
}
try {
return Promise.resolve(fn(ctx, next.bind(null, i + 1)))
} catch (err) {
Promise.reject(err)
}
}
return next(0)
}
}
class App {
constructor(){
this.middlewares = []
}
use(fn){
this.middlewares.push(fn)
return this
}
callback () {
const fn = compose(this.middlewares)
return (req, res) => {
const ctx = { req,res }
const handleResponse = () => {
console.log('handle response')
}
return fn(ctx).then(handleResponse)
}
}
listen(...args) {
const server = http.createServer(this.callback())
return server.listen(...args)
}
}
async function output1(ctx, next){
console.log('start 1')
await new Promise((resolve)=>{
setTimeout(()=>{
resolve()
},1000)
})
await next()
console.log('end 1')
}
async function output2(ctx, next){
console.log('start 2')
await new Promise((resolve)=>{
setTimeout(async ()=>{
resolve()
},2000)
})
await next()
console.log('end 2')
}
async function output3(ctx, next){
console.log('start 3')
await next()
console.log('end 3')
}
const app = new App()
app.use(output1)
app.use(output2)
app.use(output3)
app.listen(3000, ()=>{
console.log('server is running on port 3000')
})
compose
let middleware = []
middleware.push((next) => {
console.log(1)
next()
console.log(1.1)
})
middleware.push((next) => {
console.log(2)
next()
console.log(2.1)
})
middleware.push((next) => {
console.log(3)
next()
console.log(3.1)
})
let fn = compose(middleware)
fn()
/*
1
2
3
3.1
2.1
1.1
*/
//实现compose函数
function compose(middlewares) {
}