redux-saga 是一個管理 Redux 應用異步操作的中間件,功能類似redux-thunk + async/await, 它通過創建 Sagas 將所有的異步操作邏輯存放在一個地方進行集中處理。
redux-saga 的 effects
redux-saga中的 Effects 是一個純文本 JavaScript 對象,包含一些將被 saga middleware 執行的指令。這些指令所執行的操作包括如下三種:
Effects 中包含的指令有很多,具體可以異步API 參考進行查閱
redux-saga 的特點
方便測試,例如:
assert.deepEqual(iterator.next().value, call(Api.fetch, '/products'))
假如現在有一個場景:用戶在登錄的時候需要驗證用戶的 username 和 password 是否符合要求。
使用 redux-thunk 實現
獲取用戶數據的邏輯(user.js):
// user.jsimport request from 'axios';// define constants// define initial state// export default reducerexport const loadUserData = (uid) => async (dispatch) => { try { dispatch({ type: USERDATA_REQUEST }); let { data } = await request.get(`/users/${uid}`); dispatch({ type: USERDATA_SUCCESS, data }); } catch(error) { dispatch({ type: USERDATA_ERROR, error }); }}驗證登錄的邏輯(login.js):
import request from 'axios';import { loadUserData } from './user';export const login = (user, pass) => async (dispatch) => { try { dispatch({ type: LOGIN_REQUEST }); let { data } = await request.post('/login', { user, pass }); await dispatch(loadUserData(data.uid)); dispatch({ type: LOGIN_SUCCESS, data }); } catch(error) { dispatch({ type: LOGIN_ERROR, error }); }}redux-saga
異步邏輯可以全部寫進 saga.js 中:
export function* loginSaga() { while(true) { const { user, pass } = yield take(LOGIN_REQUEST) //等待 Store 上指定的 action LOGIN_REQUEST try { let { data } = yield call(loginRequest, { user, pass }); //阻塞,請求后臺數據 yield fork(loadUserData, data.uid); //非阻塞執行loadUserData yield put({ type: LOGIN_SUCCESS, data }); //發起一個action,類似于dispatch } catch(error) { yield put({ type: LOGIN_ERROR, error }); } }}export function* loadUserData(uid) { try { yield put({ type: USERDATA_REQUEST }); let { data } = yield call(userRequest, `/users/${uid}`); yield put({ type: USERDATA_SUCCESS, data }); } catch(error) { yield put({ type: USERDATA_ERROR, error }); }}
新聞熱點
疑難解答
圖片精選