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