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

深度剖析Github上15.1k Star項(xiàng)目:Redux-Thunk

開(kāi)發(fā) 項(xiàng)目管理
在解讀Redux-thunk源碼之前我們需要先掌握redux的基本工作機(jī)制和中間件實(shí)現(xiàn)原理,這樣才能更好的理解源碼背后的奧義。

[[422803]]

日益忙碌的一周又過(guò)去了,是時(shí)候開(kāi)始每周一次的總結(jié)復(fù)盤(pán)了,今天筆者就來(lái)剖析一下github中star數(shù)15.1k的開(kāi)源項(xiàng)目redux-thunk。

作為一名React方向的前端工程師,不管是被面試還是面試別人,大部分都會(huì)說(shuō)起redux-thunk的實(shí)現(xiàn)原理,因?yàn)樗浅=?jīng)典且有用,而且代碼量少的感人,只有短短12行代碼,卻能解決React開(kāi)發(fā)中同一個(gè)函數(shù)支持多dispatch和異步action的問(wèn)題(雖然這完全依賴于redux的中間件機(jī)制(Middleware))。

接下來(lái)筆者將從:

  • Redux的工作機(jī)制
  • 中間件實(shí)現(xiàn)原理
  • redux-thunk源碼實(shí)現(xiàn)

這三個(gè)方面來(lái)帶大家徹底掌握redux-thunk源碼,從而對(duì)redux有更深入的了解和應(yīng)用。如果大家對(duì)react-redux-redux-thunk實(shí)戰(zhàn)感興趣的,讀完之后可以移步筆者的《徹底掌握redux》之開(kāi)發(fā)一個(gè)任務(wù)管理平臺(tái)

正文

在解讀Redux-thunk源碼之前我們需要先掌握redux的基本工作機(jī)制和中間件實(shí)現(xiàn)原理,這樣才能更好的理解源碼背后的奧義。長(zhǎng)話短說(shuō)我們先來(lái)看看redux的幾個(gè)核心api及其作用:

redux解決的真正問(wèn)題是React組件間的狀態(tài)共享和狀態(tài)管理問(wèn)題,通過(guò)以上的6個(gè)核心api我們便能管理復(fù)雜的狀態(tài),并能監(jiān)聽(tīng)和追溯狀態(tài)的改動(dòng)。機(jī)制筆者總結(jié)如下:

redux工作機(jī)理基本了解之后,我們先看看一個(gè)實(shí)際的例子:

  1. import actionType from './actionType' 
  2.  
  3. class Actions { 
  4.     static start() { 
  5.         return { 
  6.             type: actionType.CREATE_TODO_DOING 
  7.         } 
  8.     } 
  9.  
  10.     static ok(data, cb) { 
  11.         cb && 'function' === typeof cb && cb(data); 
  12.         return { 
  13.             type: actionType.CREATE_TODO_SUCCESS, 
  14.             payload: data 
  15.         } 
  16.     } 
  17.  
  18.     static fail(data, cb) { 
  19.         cb && 'function' === typeof cb && cb(data); 
  20.         return { 
  21.             type: actionType.CREATE_TODO_FAILURE, 
  22.             payload: data 
  23.         } 
  24.     } 

以上代碼我們可以發(fā)現(xiàn)我們用了一個(gè)統(tǒng)一的createAction來(lái)創(chuàng)建action,在調(diào)用時(shí)只需要執(zhí)行Actions.start()即可,我們也知道action返回的是一個(gè)標(biāo)準(zhǔn)的對(duì)象,但我們可以在return之前做一些side effect。這里我們并不能在action中處理異步邏輯,這也是redux-thunk的價(jià)值之一,即解決異步調(diào)用action。

到這一步我們?nèi)匀徊荒苤苯舆M(jìn)入redux-thunk的源碼分析,因?yàn)槲覀冞€是不清楚如何解決上述步驟,因?yàn)槲覀冞€沒(méi)有了解redux的中間件機(jī)制。

redux中間件機(jī)制

說(shuō)到中間件(middleware),使用過(guò)nodejs的人可能會(huì)很熟悉,比如說(shuō)知名的koa中間件,express中間件等,其實(shí)中間件筆者的理解是在某個(gè)執(zhí)行流中的某個(gè)環(huán)節(jié)做一些額外的處理的模塊。實(shí)現(xiàn)中間件的機(jī)制也很簡(jiǎn)單, 就是在框架核心執(zhí)行流中去遍歷外部傳入的中間件,并依次執(zhí)行即可,我們先來(lái)看看redux中如何使用中間件的:

  1. import { createStore, applyMiddleware } from 'redux'
  2. import reducers from './reducers'
  3.  
  4. const middlewares = applyMiddleware(middleware1, middleware2); 
  5. const store = createStore(reducers, middlewares); 

所以說(shuō)redux-thunk是被傳入applyMiddleware方法中作為參數(shù)使用的,不難猜到applyMiddleware方法中一定有遍歷執(zhí)行參數(shù)的邏輯,我們來(lái)看看applyMiddleware的核心源碼:

  1. export default function applyMiddleware(...middlewares) { 
  2.     return function enhancer(createStore) { 
  3.       return function enhancedCreateStore(...args) { 
  4.         const store = createStore(...args) 
  5.         let dispatch = () => { 
  6.           thrownewError('此處省略n個(gè)字...'
  7.         } 
  8.  
  9.         const middlewareAPI = { 
  10.           getState: store.getState, 
  11.           dispatch: (...args) => dispatch(...args) 
  12.         } 
  13.  
  14.         const chain = middlewares.map(function(middleware) { 
  15.           return middleware(middlewareAPI) 
  16.         }) 
  17.  
  18.         dispatch = compose(...chain)(store.dispatch) 
  19.         return { 
  20.           ...store, 
  21.           dispatch, 
  22.         } 
  23.      } 
  24.   } 

由上面的源碼可知,在chain這段代碼里我們發(fā)現(xiàn)其存儲(chǔ)的是applyMiddleware方法參數(shù)傳入getState,dispatch后的調(diào)用結(jié)果。接下來(lái)在dispatch這段代碼中出現(xiàn)了compose函數(shù), 熟悉函數(shù)式編程的朋友不難猜到其內(nèi)部肯定是實(shí)現(xiàn)批處理chain的函數(shù),并將store.dispatch泵送至其內(nèi)部。上面源碼分析后我們知道每一次執(zhí)行dispatch時(shí),都會(huì)先經(jīng)過(guò)middleware的“洗禮”。

我們?cè)賮?lái)看看compose函數(shù)的內(nèi)部實(shí)現(xiàn):

  1. export default function compose(...funcs) { 
  2.   if (funcs.length === 0) { 
  3.     return arg => arg 
  4.   } 
  5.    
  6.   if (funcs.length === 1) { 
  7.     return funcs[0] 
  8.   } 
  9.    
  10.   return funcs.reduce(function(a, b) { 
  11.     return function (...args) { 
  12.       return a(b(...args)) 
  13.     } 
  14.   }) 

由上面代碼可以看出compose最終返回的是一個(gè)函數(shù),如果參數(shù)大于一時(shí),我們采用reduce將上一個(gè)函數(shù)返回的結(jié)果傳給下一個(gè)函數(shù)參數(shù),以此來(lái)實(shí)現(xiàn)之間的參數(shù)共享和傳遞,非常經(jīng)典的設(shè)計(jì)。

在掌握了redux中間件實(shí)現(xiàn)原理之后, 我們?cè)賮?lái)看redux-thunk源碼就非常容易理解了。

redux-thunk源碼分析

我們先看看這個(gè)github中star數(shù)15.1k的源碼長(zhǎng)啥子:

  1. function createThunkMiddleware(extraArgument) { 
  2.   return ({ dispatch, getState }) => (next) => (action) => { 
  3.     if (typeof action === 'function') { 
  4.       return action(dispatch, getState, extraArgument); 
  5.     } 
  6.  
  7.     return next(action); 
  8.   }; 
  9.  
  10. const thunk = createThunkMiddleware(); 
  11. thunk.withExtraArgument = createThunkMiddleware; 
  12.  
  13. export default thunk; 

沒(méi)錯(cuò), 這就是redux-thunk的全部源碼了,是不是很nice~。在上面的介紹中我們了解到redux中間件機(jī)制使得我們可以在中間件中拿到必備的dispatch, getState,并且在執(zhí)行之前已經(jīng)調(diào)用了兩層middleware,此時(shí)我們可以解剖一下createThunkMiddleware,在第一次調(diào)用createThunkMiddleware是在chain階段,即上面源碼分析的:

所以這里的next也就是第二次調(diào)用時(shí)的store.dispatch, 為了實(shí)現(xiàn)同一函數(shù)內(nèi)能執(zhí)行多次dispatch,我們會(huì)判斷如果action為函數(shù),則執(zhí)行action本身并把必要參數(shù)傳遞給它,否則則直接觸發(fā)dispatch,這樣我們就實(shí)現(xiàn)了支持action為函數(shù)并且支持異步多dispatch的功能了,讀到這還是非常感嘆其設(shè)計(jì)的優(yōu)雅和簡(jiǎn)潔,不經(jīng)讓筆者感嘆:學(xué)好函數(shù)式,走遍天下都不怕!

最后筆者準(zhǔn)備了一個(gè)基于React+redux+redux-thunk的實(shí)戰(zhàn)項(xiàng)目,github地址:

https://github.com/MrXujiang/redux_OA

感興趣的可以學(xué)習(xí)參考一下。

最后

如果想學(xué)習(xí)更多H5游戲, webpack,node,gulp,css3,javascript,nodeJS,canvas數(shù)據(jù)可視化等前端知識(shí)和實(shí)戰(zhàn),歡迎在公號(hào)《趣談前端》加入我們的技術(shù)群一起學(xué)習(xí)討論,共同探索前端的邊界。

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

 

責(zé)任編輯:武曉燕 來(lái)源: 趣談前端
相關(guān)推薦

2019-02-28 10:18:44

GitHub 技術(shù)開(kāi)源

2020-11-04 09:58:17

vue開(kāi)發(fā)Github

2020-10-28 09:50:05

GitHubPython項(xiàng)目

2020-02-27 09:46:19

GitHub代碼開(kāi)發(fā)者

2019-08-06 13:29:48

GitHub代碼機(jī)器學(xué)習(xí)

2021-01-13 09:42:58

站點(diǎn)隔離Chrome漏洞

2020-11-11 18:25:21

GitHub代碼 jQuery

2022-04-28 13:17:10

低代碼開(kāi)發(fā)工具

2020-11-02 14:49:46

GitHub Java圖片

2019-12-05 09:50:54

GitHub 技術(shù)深度學(xué)習(xí)

2019-02-19 10:23:53

GitHub 技術(shù)性能

2019-12-24 11:13:02

GitHub代碼開(kāi)發(fā)者

2022-09-27 18:56:28

ArrayList數(shù)組源代碼

2025-06-04 08:30:00

seata分布式事務(wù)開(kāi)發(fā)

2024-02-05 19:06:04

DartVMGC流程

2019-07-17 15:29:46

GitHub數(shù)據(jù)科學(xué)學(xué)習(xí)

2013-08-29 09:37:18

GitHub開(kāi)源項(xiàng)目

2021-05-26 09:35:22

Github開(kāi)源項(xiàng)目

2021-03-29 14:50:28

GitHub代碼開(kāi)發(fā)者

2022-05-10 09:37:18

微軟GitHub開(kāi)源軟件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲精品天堂 | 每日更新av | 一区二区三区四区免费观看 | 色网站视频 | 大香在线伊779 | 成人在线观看免费视频 | 鸡毛片 | 欧美国产激情二区三区 | 超碰av免费 | 范冰冰一级做a爰片久久毛片 | 成人免费一区二区三区视频网站 | 在线男人天堂 | 日韩在线播放视频 | 美女黄频 | 欧美一二三 | 国产99视频精品免视看9 | 亚洲欧美一区二区三区国产精品 | 黄色av网站免费看 | 羞视频在线观看 | 亚洲精品一区二区 | 午夜性视频 | 国产精品久久国产精品99 gif | 四虎永久免费地址 | 日本不卡视频在线播放 | 祝你幸福电影在线观看 | 午夜色播| 天天躁日日躁狠狠的躁天龙影院 | 性生活毛片 | 国产日韩欧美在线 | 亚洲国产精品一区在线观看 | 欧美视频在线播放 | 美女日批免费视频 | 亚洲视频在线观看 | 国产综合精品一区二区三区 | 999久久精品 | 日韩成人在线视频 | 免费精品久久久久久中文字幕 | 欧美成人免费在线 | 久久久一二三 | 91在线免费视频 | 日日干干 |