成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端代碼常見的 Provider 究竟是什么

開發 前端
不知道你有沒有在某處見過 xxProvider,provider 是提供者,從名字上和設計模式中創建對象的那些模式很像,比如工廠方法模式,但其實兩者是有區別的。

[[416082]]

不知道你有沒有在某處見過 xxProvider,Provider 并不是 23 種經典設計模式之一,但是卻應用特別多,可以算是一種比較新的模式。

  • Angular2 中提供了創建對象的時候基于 Provider
  • VSCode 插件中有各種 registerXxxProvider 的 api
  • React 提供了 Provider 組件用于 context 數據的傳遞

還有很多別的地方也經常會見到 Provider 的概念,那么 Provider 究竟是什么呢?

本文就來回答下這幾個問題:

  • provider 是什么
  • provider 創建對象和 factory 有什么區別
  • provider 的具體應用

provider 是什么

provider 是提供者,從名字上和設計模式中創建對象的那些模式很像,比如工廠方法模式,但其實兩者是有區別的。

工廠方法模式是用于創建不同的產品,通過繼承的方式。

但有的時候創建的對象可能有別的來源,比如從別的地方獲取的一個值,或者已經創建好的對象。這時候來源就不只有工廠了。

也就是說這時候要創建的對象有多種策略,工廠只是其中一種,策略 + 工廠/其他方式就是 Provider。

provider 被微軟引入到了 .net 2.0,而且微軟其他的一些技術產品也隨處可以見 provider,比如 VSCode 的 xxxProvider、angular2 的 providers。

我們來看一些具體的應用。

provider 的具體應用

VSCode 插件的 provider 系列 api

VSCode 插件中最常見的 api 就是 registerXxxProvider,通過該 api 注冊的 Provider 就是實現了 provideXxx 的對象。

比如智能補全就是注冊一個 CompletionProvider,然后根據 document 的內容,返回具體的 CompletionItem 的對象。

因為 VSCode 并不關心 CompletionItem 是怎么創建出來的,只知道通過這個 provider 可以拿到需要的 completion 數據,所以設計了 provider 的 api。

  1. const provider = vscode.languages.registerCompletionItemProvider( 
  2.         'plaintext'
  3.         { 
  4.                 provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { 
  5.                         return [ 
  6.                                 new vscode.CompletionItem('log', vscode.CompletionItemKind.Method), 
  7.                                 new vscode.CompletionItem('warn', vscode.CompletionItemKind.Method), 
  8.                                 new vscode.CompletionItem('error', vscode.CompletionItemKind.Method), 
  9.                         ]; 
  10.                 } 
  11.         }, 
  12.         '.' 
  13. ); 
  14.  
  15. context.subscriptions.push(provider); 

React 中的 context 的 Provider

react 組件樹可以在父組件放一些數據到 context 中,然后子組件取出來用,也是通過 provider 的方式。

父組件的作為 Provider 需要實現 getChildContext 方法,返回具體的對象。就像上面的 provideXxx 一樣,react 并不關心這個對象是怎么來的。

父組件里提供 getChildContext 提供數據

  1. class Ancestor extends React.Component { 
  2.   getChildContext() { 
  3.     return { value1: "context1", value2: "context2" }; 
  4.   } 
  5.   render() { 
  6.     return <Parent />; 
  7.   } 
  8.  
  9. class Parent extends React.Component { 
  10.   render() { 
  11.     return <Child /> 
  12.   } 

子組件里拿出來

  1. class Child extends React.Component { 
  2.   render() { 
  3.     console.log(this.context.value1); 
  4.   } 

當然,react 對上面的流程進行了封裝,提供了 React.createContext 的 api 和 Provider、Consumer 組件。

  1. const Context = React.createContext(); 
  2.  
  3. class Child extends React.Component { 
  4.   render() { 
  5.     return ( 
  6.       <Context.Consumer> 
  7.         {({ value1 }) => { 
  8.           console.log(value1); 
  9.         }} 
  10.       </Context.Consumer> 
  11.     ); 
  12.   } 
  13.  
  14. class Parent extends React.Component { 
  15.   render() { 
  16.     return <Child /> 
  17.   } 
  18.  
  19. class Ancestor extends React.Component { 
  20.   render() { 
  21.     return ( 
  22.       <Context.Provider value={{ 
  23.         value1: "context1" 
  24.       }}> 
  25.         <Parent /> 
  26.       </Context.Provider> 
  27.     ); 
  28.   } 

這里也是 provider 的思想。

Angular2 的 providers

angular 最大的特點就是實現了 ioc,也就是在容器內的對象,可以聲明依賴對象,然后用到的時候會自動注入。這個對象的創建方式也是 provider 的形式。

我們知道,provider 并不關心具體對象是怎么創建的,可以動態切換多種創建策略,而 angular2 就提供了 4種策略:Class、Factory、Value、Exsiting

直接值:

  1. @NgModule({ 
  2.   providers: [ 
  3.        { provide: 'ggg', useValue: 'guang' } 
  4.   ] 
  5. }) 
  6. export class MainModule { } 

已有的:

  1. @NgModule({ 
  2.   providers: [ 
  3.       { provide: 'ggg', useExisting: Guang } 
  4.   ] 
  5. }) 
  6. export class MainModule { } 

類:

  1. @Injectable() 
  2. export class Guang { 
  3.    constructor(public name: string) { 
  4.    } 
  5. @NgModule({ 
  6.   providers: [ 
  7.        { provide: 'ggg', useClass: Guang} 
  8.   ] 
  9. }) 
  10. export class MainModule { } 

工廠:

  1. function guangFactory() { 
  2.   return () => { name'guang' }; 
  3.  
  4. @NgModule({ 
  5.   providers: [ 
  6.        { provide: 'ggg', useFacotry: guangFactory } 
  7.   ] 
  8. }) 
  9. export class MainModule { } 

可以看到,angular 提供的 provider 具體的創建策略有好多種,工廠只是其中一種方式,這是 provider 和工廠的區別。

總結

provider 是一種創建對象的模式,但是和工廠不同,它是有不同的創建策略的,算是一種復合模式,工廠只是其中一種策略,這種模式在 Angular 的 ioc 創建對象的時候、VSCode 插件注冊各種處理函數的時候都有大量應用,還有 React 也基于 Provider 做 context 的傳遞。

Provider 是各種框架中頻繁出現的一個概念,掌握 provider 的思想,對于理解框架還有我們設計代碼架構都會有幫助。希望本文能夠幫大家理解 Provider。

 

責任編輯:姜華 來源: 神光的編程秘籍
相關推薦

2011-02-16 16:13:40

Debian

2019-05-27 15:30:44

Node.jsJavaScript前端

2015-09-29 09:47:14

2018-09-10 13:47:21

數據科學統計學決策

2011-08-04 13:24:28

IT運維

2012-05-28 22:49:50

PureView

2022-06-13 09:51:35

UWB超寬帶無線載波通信技術

2015-08-26 09:54:19

物聯網

2022-04-02 17:20:00

微前端應用技術

2022-06-09 10:10:24

前端組件化解耦

2014-07-28 08:28:38

Windows

2014-08-07 10:32:02

Windows微軟

2009-07-30 14:43:30

認識BSM

2020-07-08 08:09:08

邊緣計算邊緣云云平臺

2025-06-25 14:18:36

LAMLAMsGUI

2019-09-29 19:12:13

區塊鏈密碼學技術零知識證明

2022-10-19 12:23:50

緩存CDN外部緩存

2015-06-04 10:26:50

2014-06-27 09:35:16

機器學習

2021-03-08 21:44:33

以太坊區塊鏈比特幣
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品久久久久久久久中文字幕 | 一级片av| 日韩精品av一区二区三区 | 久久最新精品视频 | 精品国产一区二区三区久久影院 | av黄色免费 | 精品一区二区三区在线观看国产 | 欧美a级成人淫片免费看 | 欧美8一10sex性hd | 国产午夜精品一区二区三区在线观看 | 一区二区三区精品在线 | 亚洲一区二区中文字幕在线观看 | 情侣av| 成人国产精品久久久 | 中文字幕一二三区 | 欧美日韩三区 | 污视频免费在线观看 | 粉嫩一区二区三区性色av | caoporn免费在线视频 | 久久成人精品视频 | 在线免费小视频 | 成人激情视频在线 | 中文在线播放 | 久久一区二区视频 | 美女一级黄 | 龙珠z在线观看 | 国产精品自产拍 | 国产黄色大片 | 国产成人精品区一区二区不卡 | 久久久久久久电影 | 精品在线免费观看视频 | 欧美福利| 在线观看免费国产 | 精品视频一区二区 | 狠狠爱一区二区三区 | 国产超碰人人爽人人做人人爱 | 亚洲午夜精品久久久久久app | 亚洲精品久久区二区三区蜜桃臀 | 亚洲中国字幕 | 91麻豆精品一区二区三区 | 成人精品一区 |