如果我有两个saga在等待同一操作的yield take(),是否可以保证哪一个saga将首先获得操作并执行其剩余的逻辑,或者是随机的?我需要确保第一个传奇在第二个传奇之前执行它的逻辑。
function* rootSaga() {
yield [
saga1(),
saga2()
]
}
function* saga1() {
while (true) {
//Random logic
yield take("MY_ACTION")
//Finish executing logic
}
}
function* saga2() {
while (true) {
//Random logic
yield take("MY_ACTION")
//Finish executing logic
}
}发布于 2017-10-29 19:06:51
这里你不能依赖于执行的顺序。当您的操作被调度时,所有产生了与该操作匹配的take效果的传奇将立即恢复。如果执行的顺序是“有保证的”,那么这将是您不应该依赖的实现细节。
如果您需要在saga1执行完"MY_ACTION"之后的逻辑之后恢复您的saga2,那么您的saga2真正应该等待的是一个不同的操作,它指示saga1已经完成了它的工作,而不是第一个。
function* rootSaga() {
yield [
saga1(),
saga2()
]
}
function* saga1() {
while (true) {
//Random logic
yield take("MY_ACTION")
//Finish executing logic
yield put({type: "MY_ACTION_DONE"})
}
}
function* saga2() {
while (true) {
//Random logic
yield take("MY_ACTION_DONE")
//Finish executing logic
}
}发布于 2017-11-04 18:56:31
在执行了必要的逻辑之后,您可以从初始生成器调用或派生依赖生成器,而不是让两者独立运行。
请注意,call和fork之间有一个细微但重要的区别。call(saga2)是阻塞的,因此会暂停while循环,并且在saga2完成之前不会对任何其他"MY_ACTION"操作做出反应,而fork(saga2)是非阻塞的,其行为类似于后台任务,因此将继续并行执行您的循环恢复,因此您可以继续响应进一步的"MY_ACTION"。
另一件要注意的事情是,fork仍然附加到父saga,因此将被取消,错误将从它冒泡到父saga等。我认为这是可取的,但如果您需要一个完全独立的版本,无论父saga发生什么,都将继续运行,请使用spawn
function* rootSaga() {
yield all([
fork(saga1)
])
}
function* saga1() {
while (true) {
//Random logic
const action = yield take("MY_ACTION")
//Finish executing logic
// BLOCKING `call` saga2, passing original action as param if needed
yield call(saga2, action)
// OR NON-BLOCKING `fork` saga2
yield fork(saga2, action)
// OR NON-BLOCKING DETACHED `spawn` saga2
yield spawn(saga2, action)
}
}
function* saga2(action) {
// Do whatever dependant logic
// safe in the knowledge that saga1 has done its job already
}https://stackoverflow.com/questions/46993897
复制相似问题