摘要:大多的初學(xué)者都會(huì)使用中間件來處理異步請(qǐng)求,其理解簡(jiǎn)單使用方便具體使用可參考官方文檔。源碼的源碼非常簡(jiǎn)潔,出去空格一共只有行,這行中如果不算上則只有行。官方文檔中的一節(jié)講解的非常好,也確實(shí)幫我理解了中間件的工作原理,非常推薦閱讀。
總覺得文章也應(yīng)該是有生命力的,歡迎關(guān)注我的Github上的博客,這里的文章會(huì)依據(jù)我本人的見識(shí),逐步更新。
大多redux的初學(xué)者都會(huì)使用redux-thunk中間件來處理異步請(qǐng)求,其理解簡(jiǎn)單使用方便(具體使用可參考官方文檔)。我自己其實(shí)也一直在用,最近偶然發(fā)現(xiàn)其源碼只有一個(gè)函數(shù),考慮到其在Github上至今有6747個(gè)贊,因此比較好奇它究竟給出了一個(gè)怎么樣的函數(shù)。
什么是thunk?在看具體的源碼之前,我們先看一個(gè)詞thunk,理解這個(gè)詞有助于我們理解源碼。
redux-thunk源碼A thunk is a function that wraps an expression to delay its evaluation.
維基百科中是這樣解釋thunk的:thunk是一種包裹一些稍后執(zhí)行的表達(dá)式的函數(shù)。
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
redux-thunk的源碼非常簡(jiǎn)潔,出去空格一共只有11行,這11行中如果不算上},則只有8行。最后三行模塊的導(dǎo)出方法很好理解,
// thunk的內(nèi)容如下 ({ dispatch, getState }) => next => action => { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(action); } // thunk.withExtraArgument的結(jié)果如下 function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(action); }; }
thunk.withExtraArgument允許給返回的函數(shù)傳入額外的參數(shù),它比較難理解的部分和thunk一樣,如下:
({ dispatch, getState }) => next => action => { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(action); }
上述代碼使用函數(shù)參數(shù)的解構(gòu)加上連用三個(gè)箭頭函數(shù),顯得非常簡(jiǎn)潔,單同時(shí)也帶來了理解的困難(這也是箭頭函數(shù)的缺點(diǎn)之一)。把上述代碼在babel REPL中轉(zhuǎn)譯為ES5語(yǔ)法后,我們看到以下結(jié)果:
"use strict"; function createThunkMiddleware(extraArgument) { return function (_ref) { var dispatch = _ref.dispatch, getState = _ref.getState; return function (next) { return function (action) { if (typeof action === "function") { return action(dispatch, getState, extraArgument); } return next(); }; }; }; }
這下,代碼一下子我們能看懂了,不過稍等這里的dispatch,getState,next還有action又是什么?
我們先看看,在reudx中我們?nèi)绾问褂弥虚g件:
let store = createStore( reducer, applyMiddleware(thunk) );
看來,要解開dispatch,getState,next,action從哪里來,我們還需要再看看applyMiddleware的源碼,如下:
export default function applyMiddleware(...middlewares) { return (createStore) => (...args) => { const store = createStore(...args) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
可以看出其中middleware執(zhí)行時(shí)傳入的參數(shù)對(duì)象middlewareAPI中確實(shí)包含getState和dispatch兩項(xiàng),next則來自dispatch = compose(...chain)(store.dispatch)這一句中的store.dispatch,而action在dispatch某個(gè)action時(shí)傳入。
一般來說一個(gè)有效攜帶數(shù)據(jù)的action是如下這樣的:
{ type: ADD_TODO, text: "Build my first Redux app" }
加入redux-thunk后,action可以是函數(shù)了,依據(jù)redux-thunk的源碼,我們可以看出如果傳入的action是函數(shù),則返回這個(gè)函數(shù)的調(diào)用,如果本身傳入的函數(shù)是一個(gè)異步函數(shù),我們完全可以在函數(shù)調(diào)用結(jié)束后,獲取必要的數(shù)據(jù)再次觸發(fā)dispatch由此實(shí)現(xiàn)異步效果。
小結(jié)redux-thunk的源碼總的來說還是很簡(jiǎn)單的,理解這個(gè)函數(shù)本身并不難,但是在徹底弄懂每一項(xiàng)卻需要對(duì)reudx的部分源碼有所了解。react官方文檔中的Middleware一節(jié)講解的非常好,也確實(shí)幫我理解了中間件的工作原理,非常推薦閱讀。之前一直使用redux-thunk做異步處理,這段時(shí)間嘗試了一下redux-saga,它非常優(yōu)雅,可用于處理更加復(fù)雜的異步action,之后有時(shí)間會(huì)再總結(jié)一下它的用法,如果可以,也愿意再分析下它的源碼,歡迎關(guān)注。
相關(guān)鏈接本文在Github上的鏈接
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89347.html
摘要:的返回值是函數(shù),這個(gè)函數(shù)經(jīng)調(diào)用,傳入?yún)?shù),之后會(huì)在中間件鏈上進(jìn)行傳遞,只要保證每個(gè)中間件的參數(shù)是并且將傳遞給下一個(gè)中間件。 了解了Redux原理之后,我很好奇Redux中間件是怎么運(yùn)作的,于是選了最常用的redux-thunk進(jìn)行源碼分析。 此次分析用的redux-thunk源碼版本是2.2.0,redux源碼版本是3.7.2。并且需要了解Redux原理 redux中間件都是由redu...
摘要:接下來我們來看看源碼中的模塊是怎么應(yīng)用中間件的。如何實(shí)現(xiàn)中間件操作的。新的會(huì)從第一個(gè)中間件開始觸發(fā),這樣,在我們調(diào)用的時(shí)候,就會(huì)將中間件走一遍了。函數(shù)如果存在多個(gè)中間件,直接使用方法將各個(gè)中間件嵌套起來。 從redux-thunk引出思考 在使用redux-thunk進(jìn)行異步action書寫的時(shí)候,我經(jīng)常好奇redux到底如何運(yùn)作,讓asyncAction成為可能 為了探究,我們必須看...
摘要:上一篇文章講解了如何使用,本篇文章將進(jìn)一步深入,從的源碼入手,深入學(xué)習(xí)的中間件機(jī)制。的功能是讓支持異步,讓我們可以在中跟服務(wù)器進(jìn)行交互等操作,而他的實(shí)現(xiàn)。。。 上一篇文章講解了redux如何使用,本篇文章將進(jìn)一步深入,從redux的源碼入手,深入學(xué)習(xí)redux的中間件機(jī)制。在這里我們會(huì)以一個(gè)redux-thunk中間件為例,逐步分解redux的中間機(jī)制如何操作,如何執(zhí)行。 閑話不多說,...
摘要:舉例來說一個(gè)異步的請(qǐng)求場(chǎng)景,可以如下實(shí)現(xiàn)任何異步的邏輯都可以,如等等也可以使用的和。實(shí)際上在中,一個(gè)就是一個(gè)函數(shù)。 書籍完整目錄 3.4 redux 異步 showImg(https://segmentfault.com/img/bVyou8); 在大多數(shù)的前端業(yè)務(wù)場(chǎng)景中,需要和后端產(chǎn)生異步交互,在本節(jié)中,將詳細(xì)講解 redux 中的異步方案以及一些異步第三方組件,內(nèi)容有: redu...
摘要:然后循環(huán)調(diào)用中的更新函數(shù),更新函數(shù)一般是我們的渲染函數(shù),函數(shù)內(nèi)部會(huì)調(diào)用來獲取數(shù)據(jù),所以頁(yè)面會(huì)更新。前言 前幾天寫了一篇react另一個(gè)狀態(tài)管理工具Unstated的源碼解析。 開啟了我的看源碼之路。想一想用了好長(zhǎng)時(shí)間的redux,但從沒有深究過原理,遇到報(bào)錯(cuò)更是懵逼,所以就啃了一遍它的源碼,寫了這篇文章, 分享我對(duì)于它的理解。 API概覽 看一下redux源碼的index.js,看到了我們最...
閱讀 2950·2021-11-24 09:39
閱讀 2858·2021-09-29 09:34
閱讀 3549·2021-09-24 10:23
閱讀 1731·2021-09-22 15:41
閱讀 1690·2019-08-30 15:55
閱讀 3506·2019-08-30 13:58
閱讀 2614·2019-08-30 13:11
閱讀 1662·2019-08-29 12:31