reactjs - 使用 redux saga 阻止 takeEvery
问题描述
我有两组操作,我希望能够通过 redux 从我的应用程序的不同部分调用它们。但是,我想以正确的顺序运行它们,并确保 set b 永远不会在 set a 之前运行。
例如,假设我有两个动作,configure
并且execute
. 我需要确保它execute
之前从未运行过configure
,但它们可能会乱序发送。在这种情况下,我需要execute
排队并且只处理一次configure
完成。
这可以在 redux-saga 中做到吗?
我尝试了以下方法,似乎根本没有阻塞:
function* configureSaga({ payload }): IterableIterator<any> {
yield put(aFirstThing(payload));
yield put(aSecondThing());
}
function* executeSaga({ payload }): IterableIterator<any> {
yield put(aThirdThing(payload));
yield put(aFourthThing());
}
export function* adsSaga(): IterableIterator<any> {
const configureChanel = yield actionChannel({ type: 'configure' });
yield takeEvery(configureChanel, configureSaga);
yield takeEvery({ type: 'execute' }), executeSaga);
}
按以下顺序给定两个分派:
dispatch({ type: 'execute' })
dispatch({ type: 'configure' })
我需要按aFirstThing, aSecondThing, aThirdThing, aFourthThing
该顺序执行的操作。
redux-sagas 有可能做到这一点吗?
解决方案
takeEvery
对于最常见的情况很有用,但对于更复杂的情况,您通常最终会改为编写自定义循环。实现将根据您希望如何处理配置/执行期间调度的额外操作而有所不同。
忽略所有其他配置/执行操作(在等待第二个操作时)+ 忽略所有操作,直到配置完成:
export function* adsSaga() {
while (true) {
const [executePayload, configurePayload] = yield all([
take('configure'),
take('execute'),
])
yield call(configureSaga, configurePayload);
yield fork(executeSaga, executePayload);
}
}
忽略所有其他配置/执行操作(在等待第二个操作时)+ 缓冲所有操作,直到配置完成:
export function* rootSaga() {
const configureChan = yield actionChannel('configure');
const executeChan = yield actionChannel('execute');
while (true) {
const [executePayload, configurePayload] = yield all([
take(configureChan),
take(executeChan),
])
yield call(configureSaga, configurePayload);
yield fork(executeSaga, executePayload);
}
}
要使配置+执行操作等待每个其他人,您可以使用 all+take 的组合。只有当您想处理配置+执行组合的多“轮”时才需要 actionChannel。
您可以修改这些解决方案,例如仅缓冲配置或执行操作。或者,如果您想在配置和执行都完成之前忽略所有操作,请使用call
而不是fork
运行executeSaga
. 您还可以通过将call+fork
效果放在另一个分叉 saga 中来允许多个配置同时运行。如果您想一次最多缓冲一个动作,还可以选择将自定义缓冲区传递给动作通道。
推荐阅读
- rust - 有条件地对 Rust 中的 Vec 进行排序
- python - 为什么当我使用 state='readonly' 时条目小部件不显示文本
- rust - Using GTK and Rust. Display image on button click but change image based on variable
- google-sheets - 如何将数组添加到 AVERAGEIF(S) 公式
- amazon-s3 - 模拟后未找到 Boto3 Moto 存储桶
- java - JComponent 可见性的奇怪问题
- xml - 为什么我不能将经过处理的 xmlData 传递给 SwiftUI 中的 ContentView?
- python - 如何在多个文件夹上运行 python 来创建 pdf?
- reactjs - 使用玩笑模拟测试 axios 获得未定义
- react-native - 移动应用的技术选择