RxJS:在cycle.js自定义驱动程序中处理错误

时间:2016-04-28 19:45:35

标签: javascript reactive-programming rxjs cyclejs

我在 $("#test_default")[0].click(); 函数中实现了一些错误处理代码,如下所示。它使用main运算符来过滤和报告一个流中的错误,并在另一个流中忽略它们。这使我能够了解并报告请求发生的错误,同时不会使整个流失败,以便后续请求可以继续。

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

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

catch

输出如下:

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')
}

在正面,报告错误。但是,API请求实际上是两次,这不是我最初预期会发生的。

在学习了更多RxJS并更好地理解Hot和Cold observable之后,我意识到我正在创建两个订阅CustomDriver流(一个用于错误$和一个用于data $)并且因为CustomDriver Observable很冷,它会为每个订阅者重复some API request some API request Log Completed ERR: error Error Completed

所以我尝试使用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 导致错误丢失的原因是什么?如何在不丢失错误的情况下避免重复请求?

2 个答案:

答案 0 :(得分:2)

.shareReplay(1)似乎可以提供所需的结果。

答案 1 :(得分:1)

有一个工厂可以制作你想要的那种自定义驱动程序(来自Promises)https://github.com/whitecolor/cycle-async-driver它包括用于处理错误的助手(successfailure)。

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

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

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