2

我正在浏览 redux-saga 频道文档。我遇到代码的地方:

export function* saga() {
  const chan = yield call(countdown, value)
  try {    
    while (true) {
      let seconds = yield take(chan)
      console.log(`countdown: ${seconds}`)
    }
  } finally {
    if (yield cancelled()) {
      chan.close()
      console.log('countdown cancelled')
    }    
  }
}

如您所见,这是一个永远不会结束的无限循环,您应该调用 break 或 throw 和异常。但在上面的例子中,情况并非如此。上面的代码或调用函数中没有引发中断或异常。上面的无限循环怎么可能结束并到达finally块?

见:http: //yelouafi.github.io/redux-saga/docs/advanced/Channels.html

4

3 回答 3

2

如果您查看函数中的内容,您会看到如果不大于 0,则会发出countdown特殊END操作。secs

import { eventChannel, END } from 'redux-saga'

function countdown(secs) {
  return eventChannel(emitter => {
      const iv = setInterval(() => {
        secs -= 1
        if (secs > 0) {
          emitter(secs)
        } else {
          // this causes the channel to close
          emitter(END)
          clearInterval(iv)
        }
      }, 1000);
      // The subscriber must return an unsubscribe function
      return () => {
        clearInterval(iv)
      }
    }
  )
}

(上面的片段来自:http: //yelouafi.github.io/redux-saga/docs/advanced/Channels.html

END此处的文档中提到了该操作take(pattern):http:
//yelouafi.github.io/redux-saga/docs/api/index.html#takepattern

于 2016-08-12T17:19:11.723 回答
1

由于 redux-saga 的竞赛,上面的示例将跳出循环,这可以在此处引用的示例中找到。

示例中有一个组件,单击该组件时会调度 CANCEL_INCREMENT_ASYC 操作。传奇抓住了比赛效果的动作和火灾。

因为 incrementAsync 函数在 while 循环上运行(它基本上与您在上面发布的函数相同),所以 take(CANCEL_INCREMENT_ASYNC) 首先解析。比赛中的失败函数(上面发布的函数)会抛出一个错误,从而将 saga 恢复到finally块中。

这是可能导致取消的种族效应传奇的链接。

于 2016-07-31T09:16:41.827 回答
1

这条线似乎抛出异常,在某些调用

yield take(chan)

yield by it self 返回值,所以根本没有无限循环。

更新:关于产量如何工作的更多细节可以在这里找到https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/yield

于 2016-07-31T07:41:32.893 回答