如何在没有break语句的情况下结束while(true)循环?

时间:2016-07-31 07:35:00

标签: javascript redux redux-saga

我正在阅读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和exception。但在上面的例子中,没有一例。在调用函数上方或内部的代码中不会抛出任何中断或异常。上述无限循环如何结束并到达finally块?

请参阅:http://yelouafi.github.io/redux-saga/docs/advanced/Channels.html

3 个答案:

答案 0 :(得分:1)

这条线似乎抛出异常,在某些电话

yield take(chan)

由它自我返回值产生,因此根本没有无限循环。

更新:有关收益率如何运作的更多详细信息,请参见https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/yield

答案 1 :(得分:1)

如果您查看countdown功能中的内容,那么如果END不大于0,则会发出特殊的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

答案 2 :(得分:0)

由于redux-saga的竞争可以在引用的here示例中找到,上面的示例将突破循环。

示例中有一个组件,单击该组件将调度CANCEL_INCREMENT_ASYC操作。传奇抓住race effect的行动和火力。

因为incrementAsync函数在while循环上运行(它与上面发布的函数基本相同),所以take(CANCEL_INCREMENT_ASYNC)首先解析。比赛中失败的功能(上面发布的一个)会因为抛出一个ssmtp: Authorization failed (534 5.7.14 ...)块而导致错误抛出错误。

这是link to the race-effect saga,可能导致取消。