调用CANCEL_SEARCH时,我要取消一项传奇动作:
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);
}
cancel动作正常,但是当我导航到主屏幕并尝试进行新搜索时,不再调用getFlights动作。我在做什么错了?
答案 0 :(得分:1)
从takeLatest
返回的任务是一个监视程序任务,它监听要分派的动作GET_FLIGHTS
,而不是当前运行的getFlights
传奇。由于观察者是getFlights
传奇的父代,因此取消它也会同时取消getFlights
。
为避免取消观察者,可以用自定义循环替换takeLatest
,以便可以访问getFlights
的fork任务,也可以在两者之间添加一个传奇来处理取消:
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));
}