取消redux-saga后未调用操作

时间:2018-12-19 16:30:11

标签: reactjs redux-saga

调用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动作。我在做什么错了?

1 个答案:

答案 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));
}