Redux : 组件改变state方法是通过调用store的dispatch,触发了一个action,这个action被对应的reducer处理,改变state。在此过程中 reducer改变state是同步。而redux-saga就是将这个过程变为支持异步的。
redux-saga 和 async await 的区别是什么呢?
例如:单击按钮时从远程服务器获取一些用户数据:
普通的redux可以通过async await去请求接口,根据返回的结果改变state,改变state就是store发送dispatch,通过reducer改变state,这个是同步。异步请求接口的过程是发生在store发送dispatch之前。
redux-saga则是发生在store发送dispatch的过程中处理异步请求的。
redux saga 会先把 action 直接透传给 store,这个过程是同步的。
然后再传递一份给 watcher saga,看一下是否是被监听的 action,如果是交给 worker saga 来处理,worker saga 处理的过程中可以 put 新的 action 到 store,这个过程是异步的。
Saga 辅助函数
takeEvery:允许多个
fetchData
实例同时启动。在某个特定时刻,尽管之前还有一个或多个fetchData
尚未结束,我们还是可以启动一个新的fetchData
任务,
每次点击 Fetch 按钮时,我们发起一个 FETCH_REQUESTED
的 action。 我们想通过启动一个从服务器获取一些数据的任务,来处理这个 action。
首先我们创建一个将执行异步 action 的任务:
import { call, put } from 'redux-saga/effects'
export function* fetchData(action) {
try {
const data = yield call(Api.fetchUser, action.payload.url);
yield put({type: "FETCH_SUCCEEDED", data});
} catch (error) {
yield put({type: "FETCH_FAILED", error});
}
}
然后在每次 FETCH_REQUESTED
action 被发起时启动上面的任务。
import { takeEvery } from 'redux-saga'
function* watchFetchData() {
yield* takeEvery('FETCH_REQUESTED', fetchData)
}
takeLatest:与
takeEvery
不同,在任何时刻takeLatest
只允许一个fetchData
任务在执行。并且这个任务是最后被启动的那个。 如果已经有一个任务在执行的时候启动另一个fetchData
,那之前的这个任务会被自动取消。(始终显示最新版本的数据)
import { takeLatest } from 'redux-saga'
function* watchFetchData() {
yield* takeLatest('FETCH_REQUESTED', fetchData)
}
Effect
- take:take函数可以理解为监听未来的action,它创建了一个命令对象,告诉middleware等待一个特定的action, Generator会暂停,直到一个与pattern匹配的action被发起,才会继续执行下面的语句,也就是说,take是一个阻塞的 effect
-
put:put函数是用来发送action的 effect,你可以简单的把它理解成为redux框架中的dispatch函数,当put一个action后,reducer中就会计算新的state并返回,注意: put 也是阻塞 effect
-
call:call函数你可以把它简单的理解为就是可以调用其他函数的函数,它命令 middleware 来调用fn 函数, args为函数的参数,注意: fn 函数可以是一个 Generator 函数,也可以是一个返回 Promise 的普通函数,call 函数也是阻塞 effect
-
fork:fork 函数和 call 函数很像,都是用来调用其他函数的,但是fork函数是非阻塞函数,也就是说,程序执行完
yield fork(fn, args)
这一行代码后,会立即接着执行下一行代码语句,而不会等待fn函数返回结果后,在执行下面的语句 -
select:select 函数是用来指示 middleware调用提供的选择器获取Store上的state数据,你也可以简单的把它理解为redux框架中获取store上的 state数据一样的功能 :
store.getState()
redux-saga基本用法总结
1、使用 createSagaMiddleware 方法创建 saga 的 Middleware ,然后在创建的 redux 的 store 时,使用 applyMiddleware 函数将创建的 saga Middleware 实例绑定到 store 上,最后可以调用 saga Middleware 的 run 函数来执行某个或者某些 Middleware 。
2、在 saga 的 Middleware 中,可以使用 takeEvery 或者 takeLatest 等 API 来监听某个 action ,当某个 action 触发后, saga 可以使用 call 发起异步操作,操作完成后使用 put 函数触发 action ,同步更新 state ,从而完成整个 State 的更新。