我有一个案例,我必须打电话给n传奇:
function* mainSaga() {
yield all(
someArrayOfIds.map((id) => call(pollSaga, id))
)
}
民意调查传奇:
function* pollSaga(id) {
yield race([
call(workSaga, id)
take('STOP_ACTION')
])
}
工作传奇:
function* workSaga(id) {
while (true) {
yield call(...);
yield delay(...)
}
}
我在这里超级挣扎的事情是如何知道所有 pollSagas 何时完成。正如您在
pollSaga
中看到的,我可以只发送 STOP_ACTION
但这是无用的,因为它会停止所有的传奇(我不想立即停止所有的传奇)。
我很难正确解释这里的目标,但如果你有传奇故事的经验,你就会明白我的意思。我只是希望能够区分
pollSaga
调用,并能够分别停止每个调用,并在所有调用完成后以某种方式“监听”。
也许有办法,如果我发送
STOP_ACTION
,只取消指定的 pollSaga,而不是全部?
如果你希望能够单独停止每个工人,那么你需要在
id
动作中包含你想要停止的工人的STOP_ACTION
,然后修改race中的take
效果,以检查对于该特定 ID:
function* pollSaga(id) {
yield race([
call(workSaga, id),
take((a) => a.type === 'STOP_ACTION' && a.id === id),
])
}
// ...
yield put({type: 'STOP_ACTION', id: 'foo'})
关于你的第二个问题 - 如何知道所有工作人员何时完成 - 最简单的方法就是在
all
中的 mainSaga
效果之后运行一些代码:
function* mainSaga() {
yield all(
someArrayOfIds.map((id) => call(pollSaga, id))
)
console.log('This happens once everything is cancelled')
}
这是可行的,因为您在这里使用
call
效果,它是阻塞的,因此 mainSaga
会被阻塞在那里,直到 call
组合器中的所有 all
效果完成。