Thunk 與 Currying 概念與場景比較
Thunk
thunk 的重點在於「延遲運算」
function add(x, y) {
return x + y;
}
function thunk() {
return add(10, 20);
}
假設有 add
function,接收兩個參數進行相加,因應某個場景而需要 add(10, 20)
的結果,但不想立即運算,想要延遲執行,所以用一個 wrapper thunk
把它包起來,thunk()
被調用後才會真正執行 add(10, 20)
來看看在 redux-thunk
如何運用
thunk
是一個 function 讓我們能夠處理 async 的操作,thunk function 是能接受 dispatch 和 getState 作為參數的函式,用來產生 think function 的函式則稱作 thunk creator
// const thunkFunction = (dispatch, getState) => {...}
// 接收 dispatch 和 getState 這些函數來做為參數
// thunkFunction 內部可能會進行一些非同步操作, 如 fetch API
// API 資料接收成功後調用 dispatch
// const thunkCreator = () => (dispatch, getState) => {...}
// 接受其他參數(例如欲查詢的 id ) 來生成 thunkFunction
// 回傳一個以 (dispatch, getState) 作為參數的函數
// 就可以被 redux thunk 的 middleware所調用
const fetch_some = () => {
return (dispatch, getState) => {
doSomething();
dispatch(fooAction());
doSomethingElse();
dispatch(barAction());
};
};
function createThunkMiddleware(extraArgument) {
// 這是 middleware currying 寫法
return ({ dispatch, getState }) =>
(next) =>
(action) => {
if (typeof action === "function") {
// 在 redux-thunk 中會是 async function
// fetch_some 傳出來的 內部 thunk function 會跑來這裡
return action(dispatch, getState, extraArgument);
// 這裡才開始執行 thunk function
// 在 thunk function 內部自由使用 dispatch
// 相較於一般 redux 資料流, 這也算延遲了 dispatch 的執行
}
// 如果傳進來的 action 不是 function,則當成一般的 action 處理
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
Currying
currying 著重在單一函數,把多參數拆分成單一參數的形式,將一個接受 n 個參數的 function,轉變成 n 個只接受一個參數的 function
好處在於
- 簡化參數的處理,基本上是一次處理一個參數,藉以提高程式的彈性和可讀性
- 將程式碼依功能生成更特定功能的函數,有助於重複利用
// 多參數形式
function multiply(a, b, c) {
return a * b * c;
}
// currying 形式
function multiplyCurry(a) {
return (b) => {
return (c) => {
return a * b * c;
};
};
}
multiply(1, 2, 3); // 6
multiplyCurry(1)(2)(3); // 6
redux middleware 正好是一個 currying 的結構
const middleware = (store) => (next) => (action) => {
/* Code */
return next(action);
};
為什麼容易搞混 Currying 和 Thunk
因為在 redux 的運用中(例如 custom middleware、thunk function creator),他們都以 Higher Order Function 的形式出現,看起來很像,但是概念跟運用場景並不太一樣
Ref
Are thunk and function currying the same?
[Day 20] 用 Redux Thunk 來處理非同步 action
In simple terms, what's the difference between a thunk and a Higher Order Function?