Redux-Saga

Redux-Saga 是 Redux 的一个中间件,用于管理应用程序的所有副作用(Side Effect,如异步获取数据、访问浏览器缓存等)。Redux-Saga 使用了 ES6 的生成器功能来优化整个异步的流程。在实际应用中,可以将 Redux-Saga 想象为一个专门用于处理副作用的线程,可以从主程序启动,接受主程序控制,可以访问 Redux 的 State,并且可以分发 Action。

Redux-Saga 可以使用以下命令完成安装。

npm install redux-saga
yarn add redux-saga

Redux-Saga 已经内置了用于 TypeScript 的声明,所以如果使用 TypeScript 编写项目,不必再安装任何其他的声明库。

在 Redux-Saga 中将每个执行副作用操作的生成器称为一个 Saga,所有的 Saga 合并在一起形成一个中间件,加入到 Redux 的 Store 中。以下给出一个示例来说明其基本用法。

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware, { delay } from 'redux-saga';
import { put, takeEvery, all } from 'redux-saga/effects';

// function* 表示创建一个生成器函数。
// 其中使用yield暂停函数执行并返回当前值,并可以捕获.next()传入的参数。
function* doSomeDelayAction() {
  yield delay(1000);
  // put 辅助函数用于通知中间件发起指定 Action。
  yield put({ type: 'ACTION' });
}

// 使用 takeEvery 辅助函数监听指定的 Action,并在匹配时执行指定任务。
function* watchActions() {
  yield takeEvery('ACTION_ASYNC', doSomeDelayAction);
}

function* logSaga() {
  console.log('Log something.');
}

// 负责启动全部抛出的 Sagas
function* rootSaga() {
  yield all([logSaga(), watchActions()]);
}

const sagaMiddleware = createSagaMiddleware();
const store = createStore(reducer, applyMiddleware(sagaMiddleware));
// 启动 rootSaga 抛出的全部 Sagas
sagaMiddleware.run(rootSaga);

一般为了运行所有被创建的 Sagas,需要首先创建一个 Saga Middleware,并将这个 Saga Middleware 连接至 Redux Store。Sagas 会抛出一个可以被中间件解释执行的指令对象,当中间件取得一个被抛出的 Promise 是,Saga 将会被暂停直到 Promise 完成运行。示例中所使用的一些辅助方法其含义将逐步说明,但其功能都是用于执行某些副作用。所有的副作用都是简单 JavaScript 对象,其中包含需要中间件去执行的指令,这些副作用 Action 可以参照 Redux 的 Action 编写标准来书写。

middleware.run() 启动根 Saga 必须在 applyMiddleware() 之后,根 Saga 中可以包含所有要相应的 Action。所以建议在根 Saga 中使用 all() 来启动所有的子 Saga。