【问题标题】:Redux-saga, yield call(history.push, 'pathname'), works only the first time, blocking all other callRedux-saga,yield call(history.push, 'pathname'),只在第一次工作,阻塞所有其他调用
【发布时间】:2019-03-16 07:56:42
【问题描述】:

我正在使用 react 16.8.2

我有一个简单的 saga watcher 代码:

export default function* taskWatcher() {
  yield all([
    fork(subTaskWatcher1),
    fork(subTaskWatcher2),
  ])
}

还有一个 subWatcher 代码,

function* subTaskWatcher2() {
  const actionObj = yield take('ACTION');
  const { history } = actionObj.payload;
  let validated = false;
  //... some Computation to validate navigation ... //
  if (validated) yield call(history.push, '/pathname')
}

拦截动作并根据一些计算确定是否应将新路径推入history对象。

这仅适用于我第一次与触发上述代码的 CTA 交互。由于call saga 的影响是阻塞调用,所有其他交互都将丢失。

我的意思是,如果我导航回具有 CTA 的页面,
如果我再次点击它,现在就没有导航了。

关于thisgithub问题的讨论与我的关注有关。

我参考了this 的答案。与我的担忧无关。

当我过去遇到类似问题时,我已经浏览了文档中的 redux-saga non-blocking calls 页面。为了理解 sagas 及其影响,我缺少什么?

【问题讨论】:

  • 您是否尝试过在 taskWatcher() 中使用 takeEverytakeLatest 模式而不是 fork?
  • 这个案例我没试过。使用takeEvery 而不是fork 的原因是什么?

标签: javascript reactjs redux generator redux-saga


【解决方案1】:

根据@Jotakun 建议使用takeEvery,在saga docs 中通过takeEvery pattern 之后,以下解决方案似乎有效:

function* subTask2Worker(actionObj) {
  const { history } = actionObj.payload;
  let validated = false;
  //... some Computation to validate navigation ... //
  if (validated) yield call(history.push, '/pathname')
}

function* subTaskWatcher2() {
  yield takeEvery('ACTION', subTask2Worker);
}

export default function* taskWatcher() {
  yield all([
    fork(subTaskWatcher1),
    fork(subTaskWatcher2),
  ])
}

【讨论】: