所以我有一个像这样的传奇
function* watchSelectThing() {
let currentThing = yield select(getSelectedThing);
while (true) {
yield take(types.SELECT_THING);
const nextSelectedThing = yield select(getSelectedThing);
if (currentThing !== nextSelectedThing) {
currentThing = nextSelectedThing;
yield put(actions.updateSomeOtherThing({}));
yield put(actions.fetchOtherStuff());
}
}
}
有人告诉我,这个传奇可能会错过SELECT_THING
行动,因为选择和看跌会阻止这一行动。比如说,如果在2次投注之间触发SELECT_THING
动作。我想这似乎是合理的。
如果是这样,是否有某种方式分叉(或做其他事情),同时仍然能够保持currentThing
的必要状态,以便可以与nextSelectedThing
进行比较?我的大脑现在没有看到它。
答案 0 :(得分:1)
take
等待下一个操作发生,并且没有过去操作的缓冲区。要解决此问题,您可以使用takeLatest
。
let currentThing
function* saga() {
currentThing = yield select(getSelectedThing);
yield takeLatest(types.SELECT_THING, selectThingFlow)
}
function* selectThingFlow() {
const nextSelectedThing = yield select(getSelectedThing);
if (currentThing !== nextSelectedThing) {
currentThing = nextSelectedThing;
yield put(actions.updateSomeOtherThing({}));
yield put(actions.fetchOtherStuff());
}
}
takeLatest
和takeEvery
之间的区别在于redux-saga
如何继续或取消已执行的流程。触发takeLatest
操作后SELECT_THING
selectThingFlow
,updateSomeOtherThing
即被取消。因此,无论流程在哪里(例如fetchOtherStuff
),都不会再调用下一个操作getSelectedThing
,但流程将以takeEvery
重新启动。
selectThingFlow
但是也会从getSelectedThing
开始另一个#ifndef _DEBUG
#undef Q_ASSERT
#define Q_ASSERT(x) __noop
#undef Q_ASSERT_X
#define Q_ASSERT_X(cond, where, what) __noop
#endif
,但不会取消上一个流程的执行。