2016-04-28 90 views
3

我在main函数中实现了一些错误处理代码,如下所示。它使用catch运算符来过滤和报告一个流中的错误,并在另一个流中忽略它们。这使我可以了解并报告请求发生的错误,同时不会使整个流失败,以便后续请求可以继续。RxJS:在cycle.js自定义驱动程序中处理错误

由于在下面的代码片段中可能不明显的原因,我迫使自定义驱动程序请求和处理数据。我没有使用循环http驱动程序。

这里是我的代码,成功地报告错误:

function main(sources) { 

    // Catch driver errors so they can be logged 
    const error$ = sources.CustomDriver 
     .map(x => x.catch(e => Rx.Observable.just(e))) 
     .flatMap(p => p) 

    // Filter out the errors to deal with requests that did not fail 
    const data$ = sources.CustomDriver 
     .map(x => x.catch(e => Rx.Observable.empty())) 
     .flatMap(p => p) 

    return { 
     CustomDriver: Rx.Observable.just('initial event'), 
     Log: data$, 
     Error: error$ 
    } 
} 

Cycle.run(main, { 
    CustomDriver: makeCustomDriver(), 
    Log: msg$ => { msg$.subscribe(
     msg => console.log('LOG: ', msg), 
     err => console.log('problem with Log driver: ', err), 
     () => console.log('Log Completed') 
    ) }, 
    Error: msg$ => { msg$.subscribe(
     e => console.log('ERR: ', e), 
     err => console.log('problem with Error driver:', err), 
     () => console.log('Error Completed') 
    ) } 
}) 

function makeCustomDriver() { 
    return function customDriver(requests$) { 
     return requests$ 
      .map(request => Rx.Observable.fromPromise(makeFailedRequest())) 
    } 
} 

function makeFailedRequest() { 
    console.log('some API request') 
    return Promise.reject('error') 
} 

输出如下:

some API request 
some API request 
Log Completed 
ERR: error 
Error Completed 

加方报告错误。但是,API请求实际上是两次,这不是我预期最初发生的事情。

在学习了更多的RxJS并更好地了解了Hot和Cold可观察性之后,我意识到我正在为CustomDriver流创建两个订阅(一个针对错误$,另一个针对数据$),并且因为CustomDriver Observable很冷将为每个用户重复Observable.just

所以我试图让我的CustomDriver Observavble炎热,share

function makeCustomDriver() { 
    return function customDriver(requests$) { 
     return requests$ 
      .map(request => Rx.Observable.fromPromise(makeFailedRequest())) 
      .share() 
    } 
} 

随着这种变化,输出如下:

some API request 
Error Completed 
Log Completed 

所以我设法摆脱重复请求但这个过程中的错误被吞噬了。

发生了什么share导致错误丢失,我怎样才能避免重复的请求,而不会失去错误?

回答

2

.shareReplay(1)似乎给出了预期的结果。

1

有一个工厂用于制作您需要的自定义驱动程序(来自Promises)https://github.com/whitecolor/cycle-async-driver它包含用于处理错误的帮助程序(successfailure)。

您可以创建驱动程序就是这样:

import {makeAsyncDriver} from 'cycle-async-driver' 

    customDriver = makeAsyncDriver(
    (request) => requestHanderThatReturnsPromise(reques) 
    ) 
+0

感谢。该项目的自述文件帮助我更好地了解正在进行的操作以及制作自定义驱动程序时的一些其他注意事项。不过,我需要一些时间来消化它。在这个阶段,我宁愿修理我自己的驱动程序,而不是抽取样板文件,以便更好地理解发生了什么。我注意到正在使用'replay(null,1)'和'response $$。connect()'。这与'shareReplay(1)'相比如何? – djskinner

+0

连接将立即开始观察,shareReplay将在有第一个观察者时开始。好的,但我建议你使用这个工厂,或者你最终使用相同的样板代码库来制作一个类似的驱动程序。 – WHITECOLOR

相关问题