2016-04-28 89 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

相關問題