我正在使用saga eventChannel来监听正在触发的事件(可能是实际应用中的WebSocket),然后我正在更新Redux Store。在组件中,我正在调用API操作。然后是一个间隔(轮询),由一个传奇处理。一旦API首次成功,我将附加事件监听器。

在第二次API调用之后,我的eventChannel以某种方式终止。

EventListner:

function* countDownSaga(value) {
  const chan = yield call(countdown, value)
  try {
    while (true) {
      // take(END) will cause the saga to terminate by jumping to the finally block
      let seconds = yield take(chan)
      console.log(`countdown: ${seconds}`)
    }
  } finally {
    console.log('countdown terminated')
  }
}

Api传奇:

var countDownStarted = false

// Function to be called by saga taking action CALL_FAKE_API
function* fetchData() {
  // Simulate some server delay
  yield delay(1500)
  // Call a function
  // redux-saga "call" effect allows you to call a function
  const result = yield call(getUserData)
  yield put({ type: RECORD_USER, result })
  if(!countDownStarted) {
        yield fork(countDownSaga, 100)
        countDownStarted= true
  }
}

Jsfiddle:
https://jsfiddle.net/2d9L8fse/2/

最佳答案

实际上,不是终止事件通道,而是转到事件代码块,因为传奇本身已被取消。那是因为您使用takeLatest来运行fetchData传奇:

yield takeLatest(CALL_FAKE_API, fetchData)

并且在您的react组件中,您每15秒调度一次CALL_FAKE_API操作:
componentDidMount() {
      const { callFakeApi } = this.props
      callFakeApi()
      this.timer = setInterval(function () { callFakeApi() }, 15 * 1000)
}

如果一个fetchData传奇已在运行,并且您再次调度CALL_FAKE_API,则takeLatest将取消上一个传奇-包括其所有附加子级,例如countDownSaga传奇。

您可以尝试例如用fork替换spawn效果会创建一个分离的任务,即使取消了fetchData传奇,该任务也不会被取消。
yield spawn(countDownSaga, 100)

如果您不需要取消提取本身,则也可以将takeLatest替换为takeEvery并完全避免取消。

关于javascript - 执行另一个传奇后,Redux传奇事件 channel 终止,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58813613/

10-10 15:33