执行了另一个传奇后,Redux传奇事件通道将终止

时间:2019-11-12 07:06:32

标签: javascript reactjs redux react-redux redux-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/

1 个答案:

答案 0 :(得分:1)

实际上,不是终止事件通道,而是进入事件代码块,因为传奇本身已被取消。那是因为您使用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,并完全避免取消。