AwesomeDevin / blog

Welcome to Devin's blog,I'm trying to be a fullstack developer and sticking with it !!!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

express / koa 中间件模型的实现

AwesomeDevin opened this issue · comments

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) {
    
}