前言
由于redux本身只支持同步数据流,对于异步数据流,需要通过中间件来解决, 学习中间件前,需要掌握ES6的。redux-saga作为一个完善的中间件,包括了监听,阻塞,派送未来的action, 获取当前state等等好用的API。
API
监听并且阻塞Action
对于一个redux异步数据流,通常始与监听到一个指定的Action,然后自动执行接下来的数据流1
2const action = yield take('Request');
//接下来可以使用call函数来执行指定的saga
take函数可以监听并阻塞一次Action,参数为Action的名称,该函数的返回值为Action的内容
1 | import { takeEvery } from `redux-saga/effects` |
takeEvery的用处如同其名称一样,每次该Action被派送时,都会被监听到。第一个参数也是Action的名称,第二个参数为监听到该Action时,需要执行的函数。这里我们间听到“Request”这个Action时,会出发fetchData方法,去获取服务器的数据。
1 | yield takeLatest('USER_REQUESTED', fetchUser) |
有时候用户可能会意外地多次触发了Action(例如提交表单的时候),这可能造成用户频繁的访问服务器(重复提交表单),为了防止这种无意义的行为,可以使用takeLateast。takeLatest会将传入的saga作为一个task去执行,如果前一个task还没有执行完,又监听到了相同的Action,则会自动取消该task,因此最后执行的saga则是短时间内用户第一次的操作。1
2
3
4
5
6
7
8
9
10const takeLatest = (patternOrChannel, saga, ...args) => fork(function*() {
let lastTask
while (true) {
const action = yield take(patternOrChannel)
if (lastTask) {
yield cancel(lastTask) // cancel is no-op if the task has already terminated
}
lastTask = yield fork(saga, ...args.concat(action))
}
}
当然在一般情况下,我们可以直接使用take更加简单粗暴的阻塞数据流,同样可以防止后面的表单提交数据流的执行。