取消redux-saga后不调用动作
Action is not called after being canceled redux-saga
调用 CANCEL_SEARCH 时我正在取消 saga 操作:
function* cancelWorkerSaga(task) {
console.log(task);
yield cancel(task);
}
export default function* sagaFlights() {
const workerTask = yield takeLatest(GET_FLIGHTS, getFlights);
yield takeLatest(CANCEL_SEARCH, cancelWorkerSaga, workerTask);
}
取消操作工作正常,但是当我导航到主屏幕并尝试进行新搜索时,getFlights 操作不再被调用。我做错了什么?
从 takeLatest
返回的任务是一个观察者任务,它侦听要分派的操作 GET_FLIGHTS
,而不是当前的 运行 getFlights
saga。由于观察者是 getFlights
saga 的父级,取消它也会取消 getFlights
。
为了避免取消观察者,您可以将 takeLatest
替换为自定义循环,这样您就可以访问 getFlights
的 fork 任务,或者您可以在两者之间再放置一个 saga 来处理取消:
export default function* sagaFlights() {
yield takeLatest(GET_FLIGHTS, function*(...args) {
yield race([
call(getFlights, ...args),
take(CANCEL_SEARCH)
]);
});
}
如果您经常需要这种模式,您可以创建一个简单的实用函数来隐藏逻辑:
const cancelable = (saga, cancelAction) => function*(...args) {
yield race([call(saga, ...args), take(cancelAction)]);
};
function* rootSaga() {
yield takeLatest(GET_A, cancelable(getA, CANCEL_A));
yield takeLatest(GET_B, cancelable(getB, CANCEL_B));
}
调用 CANCEL_SEARCH 时我正在取消 saga 操作:
function* cancelWorkerSaga(task) {
console.log(task);
yield cancel(task);
}
export default function* sagaFlights() {
const workerTask = yield takeLatest(GET_FLIGHTS, getFlights);
yield takeLatest(CANCEL_SEARCH, cancelWorkerSaga, workerTask);
}
取消操作工作正常,但是当我导航到主屏幕并尝试进行新搜索时,getFlights 操作不再被调用。我做错了什么?
从 takeLatest
返回的任务是一个观察者任务,它侦听要分派的操作 GET_FLIGHTS
,而不是当前的 运行 getFlights
saga。由于观察者是 getFlights
saga 的父级,取消它也会取消 getFlights
。
为了避免取消观察者,您可以将 takeLatest
替换为自定义循环,这样您就可以访问 getFlights
的 fork 任务,或者您可以在两者之间再放置一个 saga 来处理取消:
export default function* sagaFlights() {
yield takeLatest(GET_FLIGHTS, function*(...args) {
yield race([
call(getFlights, ...args),
take(CANCEL_SEARCH)
]);
});
}
如果您经常需要这种模式,您可以创建一个简单的实用函数来隐藏逻辑:
const cancelable = (saga, cancelAction) => function*(...args) {
yield race([call(saga, ...args), take(cancelAction)]);
};
function* rootSaga() {
yield takeLatest(GET_A, cancelable(getA, CANCEL_A));
yield takeLatest(GET_B, cancelable(getB, CANCEL_B));
}