take(pattern)
使用take操作进行事件监听,用来命令 middleware 在 Store 上等待指定的 action。 在发起与 pattern 匹配的 action 之前,Generator 将暂停(eg:下一个请求的参数依赖前一个请求的结果)。
*fetchList({ payload, callback }, { call, put, select, take }) {
yield put({
type: 'dict/xxxx',
payload: {
...
},
});
yield take('dict/xxxx/@@end');
const dictData = yield select(state => state.dict.dicts);
const response = yield call(getList, {
xxx: dictData.xxx
...
});
}
race(effects)
任务的竞争,用来命令 middleware 在多个 Effect 间运行 竞赛(Race)(与 Promise.race([…]) 的行为类似)。
*fetchList({ payload, callback }, { race }) {
const { list, timeout } = yield race({
list: call(services.fetchList),
timeout: call(delay, TIMEOUT),
});
if (timeout) {
throw new Error('timeout');
}
}
任务的并行执行
把多个要并行执行的东西放在一个数组里,就可以并行执行,等所有的都结束之后,进入下个环节,类似promise.all的操作。一般有一些集成界面,比如dashboard,其中各组件之间业务关联较小,就可以用这种方式去分别加载数据,此时,整体加载时间只取决于时间最长的那个。
之前是 yield [], 后来 dva 升级了 saga 的版本之后就推荐用 yield all([])
*yield []
*fetchList({ payload, callback }, { }) {
const [xx1_req, xx2_req, xx3_req] = yield [
call(xx1, payload),
call(xx2, payload),
call(xx3, payload),
]
}
*yield all([])
*fetchList({ payload, callback }, { all }) {
const [xx1_req, xx2_req, xx3_req] = yield all([
call(xx1, payload),
call(xx2, payload),
call(xx3, payload),
])
}