Skip to main content

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

[Redux] Redux Thunk

In simple terms, what's the difference between a thunk and a Higher Order Function?

[FP] Currying