疑難排解
加入 saga 後,應用程式凍結
請確定你從產生器函數中yield
效果。
考慮以下範例
import { take } from 'redux-saga/effects'
function* logActions() {
while (true) {
const action = take() // wrong
console.log(action)
}
}
這會讓應用程式進入無限迴圈,因為take()
只會建立效果的描述。除非你讓中介軟體對其yield
以執行,否則while
迴圈會像一般的while
迴圈般執行,並讓你的應用程式凍結。
加入yield
會暫停產生器,並將控制權交還給 Redux Saga 中介軟體,由其執行效果。對於take()
,Redux Saga 將會等待符合模式的下一個動作,並在等到後才會恢復執行產生器。
若要修正上面的範例,請對由take()
傳回的效果yield
import { take } from 'redux-saga/effects'
function* logActions() {
while (true) {
const action = yield take() // correct
console.log(action)
}
}
我的 Saga 漏了某些已發送的動作
請確認該傳奇人物不受某些效應阻擋。傳奇人物在等待效應解決時,將無法採取分派動作,直到該效應得到解決。
例如,考慮這個範例
function* watchRequestActions() {
while (true) {
const { url, params } = yield take('REQUEST')
yield call(handleRequestAction, url, params) // The Saga will block here
}
}
function* handleRequestAction(url, params) {
const response = yield call(someRemoteApi, url, params)
yield put(someAction(response))
}
當 watchRequestActions
執行 yield call(handleRequestAction, url, params)
,它將等待 handleRequestAction
,直到它終止並返回,然後繼續進行下一個 yield take
。例如,假設我們有這個事件順序
UI watchRequestActions handleRequestAction
-----------------------------------------------------------------------------
.......................take('REQUEST').......................................
dispatch(REQUEST)......call(handleRequestAction).......call(someRemoteApi)... Wait server resp.
.............................................................................
.............................................................................
dispatch(REQUEST)............................................................ Action missed!!
.............................................................................
.............................................................................
.......................................................put(someAction).......
.......................take('REQUEST')....................................... saga is resumed
如上圖所示,當傳奇人物被 封鎖呼叫 阻擋時,它將遺漏其間分派的所有動作。
若要避免封鎖傳奇人物,你可以使用 fork
代替 call
使用 非封鎖呼叫
function* watchRequestActions() {
while (true) {
const { url, params } = yield take('REQUEST')
yield fork(handleRequestAction, url, params) // The Saga will resume immediately
}
}
傳遞到根傳奇人物的錯誤的錯誤堆疊無法讀取
根據其性質,傳奇人物中的任務是異步的,因此我們必須做一些額外的作業才能顯示「傳奇人物堆疊」,因為它是同步呼叫鏈。因此,從 redux-saga@v1
開始,當錯誤傳遞到根傳奇人物時,函式庫會建置該「傳奇人物堆疊」,並將其傳遞為 onError
呼叫的第二個引數的 sagaStack: string
屬性(另請參閱中介軟體選項),因此你可以將其傳送至你的錯誤追蹤系統或進行其他額外的作業。
因此,你可以在主控台中看到類似這樣的內容。
如果你想在開發目的中使用具有檔案名稱和行號的「傳奇人物堆疊」,你可以新增babel-plugin,它允許你獲得增強的資訊。文件 在此。有關 babel-plugin 使用範例,請查看此範例。
新增 babel-plugin-redux-saga
之後,相同的輸出如下所示
註:它也適用於測試,只要確保你(或你的執行者)透過 sagaMiddleware
執行傳奇人物即可。