与在循环中调度动作和单独跟踪进度混淆

Confusion with dispatching an action in loop and tracking progress individually

我正在调度一个动作,让我们说“GET_STATUS”在一个循环中从一个组件持续 X 次。 在 saga 文件中我有

function* actionWatcher() {
    yield all([
        takeLatest(Actions.GET_LATEST, getLatest),
    ]);
}

getLatest* 函数中有这个 API 调用

//Some code
const results = yield call(api, {params});
//code after
callback()

我可以清楚地看到 API 在网络中被调用 X 次,在 chrome 调试器中我也可以看到 //Some code 被执行 X 次。但是 //code after 最后只执行一次, callback 函数最后只被调用一次。 我期待每次出现都会被叫到。

如果多个Actions.GET_LATEST快速连续发生,那么takeLatest旨在取消旧的saga,并开始一个新的saga。如果 saga 在执行 const results = yield call(api, {params}); 时被取消,这意味着它永远不会到达 callback()

如果您不想取消它们,请使用 takeEvery 而不是 takeLatest

function* actionWatcher() {
    yield all([
        takeEvery(Actions.GET_LATEST, getLatest),
    ]);
}

如果你想保留取消,但你需要在取消时调用回调,你可以使用try/finally:

function* getLatest() {
  try {
    const results = yield call(api, {params});
  } finally {
    // This code will run whether it completes successfully, or throws an error, or is cancelled
    callback();
  }
}

如果您需要专门检查它是否被取消以执行自定义逻辑,您可以在 finally 块中使用 if (yield cancelled()) 来实现:

function* getLatest() {
  try {
    const results = yield call(api, {params});
    callback(); // This line will only run if it's not cancelled and does not throw
  } finally {
    if (yield cancelled()) {
      // This line will only run if cancelled
    }
  }
}