iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0
Modern Web

前端技術研究系列 第 16

Redux Saga 基礎 Effect (上集)

  • 分享至 

  • xImage
  •  

基礎概念

Saga 被實作為 Generator function(function*),yield 物件到 redux-saga middleware。被 yield 的物件是一種指令,透過 middleware 被解讀。當一個 Promise 被 yield 到 middleware,middleware 將暫停 Saga,直到 Promise 完成。一旦 Promise 被 resolve,middleware 將恢復 Saga,執行程式碼直到下一次的 yield。

effect們(來自官網):https://redux-saga.js.org/docs/api
一樣族繁不及備載會針對一些常用的來做研究,目前會先分享一些基礎概念及應用,就很夠用了,進階概念先不提,有興趣的人可以去看官網

  • 補充:yield計算右側的任何表達式,然後將結果return給調用者

Effect(一個常見的抽象概念)

Effect 是一些簡單的 JavaScript 物件,包含由 middleware 實現的說明。當一個 middleware 透過 Saga 取得一個被 yield 的 Effect,Saga 會被暫停,直到 Effect 被完成。

從 Saga 內觸發異步操作(Side Effect),是透過 yeild 一些聲明式 Effect 來達成的。Saga 所做的實際上是組合所有effect,以及其他運算子(ifwhilefor),來實現所需或是更複雜的控制流程。

這些Effect(put , call , takeEvery)相結合,能實現與 redux-thunk 相同的效果,不過當邏輯判斷更為複雜時,Saga 仍舊比 redux-thunk 更易於測試。

Dispatching actions (to the store)

keywords: put

  • put(action)
    =>建立一個 Effect 描述來說明 middleware 去 dispatch 一個 action 到 Store。

put可以作為 dispatch觸發 Reducer,使用方式也和 dispatch 相同,不過如同先前所提到的,yield會在前者成功後執行後續動作,如果我們想測試成功call完api,才去執行後續就會需要用到put了。

function* fetchData(dispatch) {
  const data= yield call(apiFunction, arg)
  dispatch(setDate(data))
}

function* fetchProducts() {
  const data= yield call(apiFunction, arg)
  // 建立並 yield 一個 dispatch
  yield put(setDate(data));
  // 原先被 dispatch 觸發的 Method 從 Reducer 變成 Redux - Saga 
}

Declarative Effects (處理非同步事件)

keywords: callapplycps
僅引用方法不同,不過功能大致相同

  • call(fn, ...args)
    =>建立一個 Effect 描述,指示 middleware 呼叫 function fn和 args為參數。

call就像 put,透過他們本身執行任何 dispatch 或非同步的呼叫,它們只是簡單回傳純 JavaScript 的物件。
如果 Effect 的類型是一個 PUT,他將 dispatch 一個 action 到 Store。
如果 Effect 是一個 CALL,它呼叫給定的 function。

這是是將建立 Effect (put)和執行 Effect (call)分離的作法

put({type: 'INCREMENT'}) // => { PUT: {type: 'INCREMENT'} }
call(delay, 1000)        // => { CALL: {fn: delay, args: [1000]}}

接下來還有 Error handling & Using Saga Helpers
字數太多分兩天發~


上一篇
Redux Saga 基礎認識
下一篇
Redux Saga 基礎 Effect (下集)
系列文
前端技術研究30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言