RxJs - 为什么Rx.Observable.fromNodeCallack(...)(...)。retry()不会在出错时重试?

时间:2015-06-15 06:11:12

标签: rxjs

我想知道为什么以下代码(在coffeescript中)不会按预期重试。

Rx = require 'rx'

count = 0

functToTest = (cb) ->
  console.log "count is", count
  count++
  if count is 1
    cb(new Error('some error'))
  else if count is 2
    cb(null,2)
  else if count is 3
    cb(null,3)
  else
    cb(null,4)


source = Rx.Observable.fromNodeCallback(functToTest)()

onNext = (value) ->
  console.log value

onError = (err) ->
  console.log err

onCompleted = ->
  console.log "done"

retryableSrc = source.retry(3)

retryableSrc.subscribe(onNext, onError, onCompleted)

它将输出以下消息并退出

count is 0
[Error: some error]

我原以为这可能是因为fromNodeCallback()返回一个热的observable。但是如下的测试表明它不是。

Rx = require 'rx'

count = 0

functToTest = (cb) ->
  console.log "count is", count
  count++
  if count is 1
    cb(new Error('some error'))
  else if count is 2
    cb(null,2)
  else if count is 3
    cb(null,3)
  else
    cb(null,4)


source = Rx.Observable.fromNodeCallback(functToTest)()

onNext = (value) ->
  console.log value

onError = (err) ->
  console.log err

onCompleted = ->
  console.log "done"

retryableSrc = source.retry(3)

setTimeout ( -> ), 1000

如果它是一个热点可观察,上面的程序应该打印一些"计数是0"信息。但实际上程序只等了1秒就退出了。

1 个答案:

答案 0 :(得分:3)

它实际上很热,或者在您第一次订阅时很热。

fromNodeCallback内部是Rx.Observable.create(...).publishLast().refCount(),这意味着当您第一次订阅时,它将执行方法,打印计数然后发出错误。错误将通过重试捕获到下游,这将仅重新订阅三次以接收缓存错误,它将最终自行发出。

您可以使用flatMap

修复它
ncb = Rx.Observable.fromNodeCallback(functToTest);    
source = Rx.Observable.just(ncb).flatMap((fn) -> fn());