日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
淺析洋蔥模型

 [[407985]]

前言

使用過(guò)koa的小伙伴們都應(yīng)該對(duì)洋蔥模型有所了解,koa的獨(dú)特的中間件流程控制就是通過(guò)洋蔥模型來(lái)實(shí)現(xiàn)的,那么洋蔥模型是什么,又是如何實(shí)現(xiàn)的呢?

專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)贛榆免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

洋蔥模型介紹

介紹

上圖是洋蔥模型比較經(jīng)典的一個(gè)圖,通過(guò)這個(gè)圖可以看到,洋蔥模型就像一個(gè)洋蔥一個(gè),是分成多層的,而一個(gè)請(qǐng)求進(jìn)入的時(shí)候,會(huì)從外到內(nèi)依次經(jīng)過(guò)每一層,到最內(nèi)側(cè)之后又從內(nèi)到外依次經(jīng)過(guò)每一次,而我們就可以在這每一層上面做自己需要做的操作。

比如一個(gè)請(qǐng)求,在koa接收到請(qǐng)求的時(shí)候,首先需要鑒權(quán),然后需要對(duì)請(qǐng)求參數(shù)解析等等,完成請(qǐng)求之后,需要處理異常,添加請(qǐng)求頭等等操作,而這些操作就可以放到洋蔥模型的每一層上面做處理。

示例代碼

如下代碼為koa的一段示例代碼:

 
 
 
 
  1. const Koa = require('koa'); 
  2. const app = new Koa(); 
  3.  
  4. app.use(async (ctx, next) => { 
  5.   console.log(1); 
  6.   await next(); 
  7.   console.log(2); 
  8. }); 
  9.  
  10. app.use(async (ctx, next) => { 
  11.   console.log(3); 
  12.   await next(); 
  13.   console.log(4); 
  14. }); 
  15. app.use(async (ctx, next) => { 
  16.   console.log(5); 
  17.   await next(); 
  18.   console.log(6); 
  19. }); 
  20.  
  21. app.listen(8000); 

執(zhí)行上面的代碼,會(huì)發(fā)現(xiàn)輸出的數(shù)字順序?yàn)?,3,5,6,4,2,與上面介紹的洋蔥模型的執(zhí)行順序是一致的。

洋蔥模型實(shí)現(xiàn)

首先我們先分析一下上面的代碼app.use傳入了一個(gè)異步的函數(shù),而且app.use可以被使用多次,而這些函數(shù)在請(qǐng)求進(jìn)入的時(shí)候會(huì)依次被調(diào)用,這是不是與發(fā)布訂閱者模式是一致的,那首先我們來(lái)實(shí)現(xiàn)一個(gè)app.use

實(shí)現(xiàn)一個(gè)app.use

 
 
 
 
  1. export interface Middleware { 
  2.   (...rest: any): Promise
  3.  
  4. export default class Onion { 
  5.   middlewares: Middleware[] = []; 
  6.   constructor(middlewares: Middleware[] = []) { 
  7.     this.middlewares = middlewares; 
  8.   } 
  9.  
  10.   use(middleware: Middleware) { 
  11.     this.middlewares.push(middleware); 
  12.   } 

上面代碼我們定義了一個(gè)Onion類,通過(guò)這個(gè)類我們就可以將訂閱函數(shù)進(jìn)行收集,如下代碼所示

 
 
 
 
  1. const onion = new Onion() 
  2. onion.use(async(params, next)=> { 
  3.    console.log(1) 
  4.    await next() 
  5.    console.log(2) 
  6. }) 

發(fā)布者在收集完訂閱函數(shù)后需要有觸發(fā)的時(shí)機(jī),這時(shí)候就需要再給Onion添加一個(gè)執(zhí)行函數(shù)

完善Onion

有小伙伴想到發(fā)布訂閱者的實(shí)現(xiàn)代碼,可能就會(huì)想到這樣做:

 
 
 
 
  1. export default class Onion { 
  2.   middlewares: Middleware[] = []; 
  3.   constructor(middlewares: Middleware[] = []) { 
  4.     this.middlewares = middlewares; 
  5.   } 
  6.  
  7.   use(middleware: Middleware) { 
  8.     this.middlewares.push(middleware); 
  9.   } 
  10.  
  11.   execute(params: any) { 
  12.     this.middlewares.forEach(fn => { 
  13.           fn(params) 
  14.        }) 
  15.   } 

但是這樣做的話,就無(wú)法滿足洋蔥模型的先入后出的順序,那我們應(yīng)該怎么做呢?

1.定義 compose函數(shù)

 
 
 
 
  1. function compose(middlewares: Array) { 
  2. if (!Array.isArray(middlewares)) { 
  3.  throw new Error('中間件必須是數(shù)組'); 
  4. for (let i = 0; i < middlewares.length; i++) { 
  5.  if (typeof middlewares[i] !== 'function') { 
  6.    throw new Error('中間件的每一項(xiàng)都必須是函數(shù)'); 
  7.  } 
  8.  
  9. return (params: any) => { 
  10.  let index = 0; 
  11.  function dispatch(fn: Middleware | undefined) { 
  12.    if (!fn) { 
  13.      return Promise.resolve(); 
  14.    } 
  15.    const next = () => dispatch(middlewares[++index]); 
  16.    return Promise.resolve(fn(params, next)); 
  17.  } 
  18.  return dispatch(middlewares[index]); 
  19. }; 

2.實(shí)現(xiàn)execute

 
 
 
 
  1. export default class Onion { 
  2. middlewares: Middleware[] = []; 
  3. constructor(middlewares: Middleware[] = []) { 
  4.  this.middlewares = middlewares; 
  5.  
  6. use(middleware: Middleware) { 
  7.  this.middlewares.push(middleware); 
  8.  
  9. execute(params: any) { 
  10.  const fn = compose(this.middlewares); 
  11.  return fn(params); 

通過(guò)定義componse函數(shù),可以將中間件函數(shù)依次按照順序來(lái)執(zhí)行。

 
 
 
 
  1. const onion = new Onion(); 
  2. onion.use(async (params: any, next: Middleware) => { 
  3.  console.log(1); 
  4.  await next(); 
  5.  console.log(2); 
  6. }); 
  7.  
  8. onion.use(async (params: any, next: Middleware) => { 
  9.  console.log(3); 
  10.  await next(); 
  11.  console.log(4); 
  12. }); 
  13.  
  14. onion.use(async (params: any, next: Middleware) => { 
  15.  console.log(5); 
  16.  await next(); 
  17.  console.log(6); 
  18. }); 
  19.  
  20. onion.execute({}); 

這樣我們就實(shí)現(xiàn)了一個(gè)簡(jiǎn)易版的洋蔥模型。

本文轉(zhuǎn)載自微信公眾號(hào)「前端有的玩」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系前端有的玩公眾號(hào)。


當(dāng)前題目:淺析洋蔥模型
轉(zhuǎn)載源于:http://www.dlmjj.cn/article/dpeghcp.html