Koa和Express的非同步中介軟體解決辦法

進階的巨人001發表於2020-11-12

express和koa框架他們的核心其實都是中介軟體,但是他們的中介軟體事實上,它們的中介軟體的執行機制是不同的,特別是針對某個中介軟體中包含非同步操作時

舉個例子:

在這裡插入圖片描述
先來看express同步實現

const middleware1 = (req,res,next)=>{
  req.message = 'aaa'
  next()
  res.end(req.message) // 'aaabbbccc'
}

const middleware2 = (req,res,next)=>{
  req.message += 'bbb'
  next()
}

const middleware3 = (req,res,next)=>{
  req.message += 'ccc'
}

res.end(req.message)返回’aaabbbccc’,這是為啥呢??

因為它是從上往下執行,當執行到next的時候,它會重新進行匹配,因為第一個已經執行完了,但是res.end在next後面並沒有被執行,所以直接執行第2個,然後依次當最後一個執行完了,然後原路返回,當執行到res.end時候,req.message裡面就為’aaabbbccc’了

先來看express非同步實現

const middleware1 = (req,res,next)=>{
  req.message = 'aaa'
  next()
  res.end(req.message) 
}

const middleware2 = (req,res,next)=>{
  req.message += 'bbb'
  next()
}

const middleware3 = (req,res,next)=>{
  axios.get('').then((res)=>{
    req.message += res.data    //假如這個結果為ccc
  })
}

此時res.end(req.message) 返回的是’aaabbb’,這是為啥?

當middleware3裡面是非同步的話,它不會管middleware3執行完沒有,會直接向下執行,咋解決呢?

把req.message放到middleware3裡面,axios後面即可

但是我們就想在middleware1裡面獲取res.message咋辦?

那你如果把middleware3當成一箇中介軟體的話,就不好做了,就直接把它當成一個函式,在middleware1裡面執行

express處理非同步有點乏力,所以就有了koa

再來看koa同步實現

const middleware1 = (ctx,next)=>{
  ctx.message = 'aaa';
  next()
  ctx.body = ctx.message  //'aaabbbccc'
}

const middleware2 = (ctx,next)=>{
  ctx.message += 'bbb'
  next()
}

const middleware3 = (ctx,next)=>{
  ctx.message += 'ccc'
}

同步沒啥區別,關鍵是非同步

再來看koa非同步實現

const middleware1 = async (ctx,next)=>{
  ctx.message = 'aaa';
  await next()
  ctx.body = ctx.message  //'aaabbbccc'
}

const middleware2 = async (ctx,next)=>{
  ctx.message += 'bbb'
  await next()
}

const middleware3 = (ctx,next)=>{
  const result = await axios.get('')
  ctx.message += result.data   //假如為ccc
}

此時ctx.body為’aaabbbccc’,那是為什麼呢?

因為在koa中,next它的原理其實是一個promise,這個看它的原始碼就可以知道,我們在前面加了await將它變成同步操作,會從上往下依次執行,有結果了才會接著進行

相關文章