admin管理员组文章数量:1289845
If i have two sagas waiting for a yield take()
on the same action, is there a guarantee which saga will pick up the action first and execute its remaining logic or is random? I need to ensure the first saga executes its logic before the second saga does.
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
}
}
If i have two sagas waiting for a yield take()
on the same action, is there a guarantee which saga will pick up the action first and execute its remaining logic or is random? I need to ensure the first saga executes its logic before the second saga does.
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
}
}
Share
Improve this question
edited Oct 28, 2017 at 20:20
Gabriel West
asked Oct 28, 2017 at 19:58
Gabriel WestGabriel West
9412 gold badges12 silver badges25 bronze badges
2 Answers
Reset to default 6You cannot rely here on the order of execution. When your action is dispatched, all sagas that have yielded a take
effect matching the action will be resumed at once. If an order of execution was "guaranteed", it would be an implementation detail you shouldn't rely on.
If you need your saga2
to be resumed after saga1
has executed the logic subsequent to "MY_ACTION"
, what your saga2
should really be waiting for is a different action indicating that saga1
has finished its job, rather than the first one.
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
}
}
Rather than having both run independently, you can call or fork the dependent generator from the initial one after the necessary logic has been performed.
Note there is a subtle but important difference between call
and fork
. call(saga2)
is blocking so would pause your while loop and not react to any more "MY_ACTION"
actions until saga2 has pleted too, whereas fork(saga2)
is non-blocking, acting like a background task so would continue to execute in parallel to your loop resuming, so you could continue to respond to further "MY_ACTION"
.
Another thing to note is that fork
is still attached to the parent saga, so will be cancelled along with it, errors will bubble to parent from it etc. I imagine this is desirable but if you need a pletely detached version that will continue to run no matter what happens to parent saga, use spawn
instead
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
}
本文标签: javascriptReduxSaga Is there a guaranteed order of saga executionStack Overflow
版权声明:本文标题:javascript - Redux-Saga: Is there a guaranteed order of saga execution? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741397426a2376462.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论