admin管理员组

文章数量:1290176

My use case is to map an Observable to redux actions of success and failure. I make a network call (with a function that gives promise), if it succeeds I have to forward a success action, if it fails than an error action. The Observable itself shall keep going. For all I could search, RxJS do not have a mechanism for this catching the error and retrying the original. I have following solution in my code which I am not happy with:

error$ = new Rx.Subject();

searchResultAction$ = search$
    .flatMap(getSearchResultsPromise)
    .map((resuls) => {
        return {
            type: 'SUCCESS_ACTION',
            payload: {
                results
            }
        }
    })
    .retryWhen((err$) => {
        return err$
            .pluck('query')
            .do(error$.onNext.bind(error$));
    });

searchErrorAction$
    .map((query) => {
        return {
            type: 'ERROR_ACTION',
            payload: {
                query,
                message: 'Error while retrieving data'
            }
        }
    });

action$ = Observable
    .merge(
        searchResultAction$,
        searchErrorAction$
    )
    .doOnError(err => console.error('Ignored error: ', err))
    .retry();

action$.subscribe(dispatch);

i.e I create a subject, and push errors into that subject and create an Observable of error actions from that.

Is there a better alternative of doing this in RxJS that I am missing? Basically I want to emit a notification of what error has occurred, and then continue with whatever the Observable is already doing.

My use case is to map an Observable to redux actions of success and failure. I make a network call (with a function that gives promise), if it succeeds I have to forward a success action, if it fails than an error action. The Observable itself shall keep going. For all I could search, RxJS do not have a mechanism for this catching the error and retrying the original. I have following solution in my code which I am not happy with:

error$ = new Rx.Subject();

searchResultAction$ = search$
    .flatMap(getSearchResultsPromise)
    .map((resuls) => {
        return {
            type: 'SUCCESS_ACTION',
            payload: {
                results
            }
        }
    })
    .retryWhen((err$) => {
        return err$
            .pluck('query')
            .do(error$.onNext.bind(error$));
    });

searchErrorAction$
    .map((query) => {
        return {
            type: 'ERROR_ACTION',
            payload: {
                query,
                message: 'Error while retrieving data'
            }
        }
    });

action$ = Observable
    .merge(
        searchResultAction$,
        searchErrorAction$
    )
    .doOnError(err => console.error('Ignored error: ', err))
    .retry();

action$.subscribe(dispatch);

i.e I create a subject, and push errors into that subject and create an Observable of error actions from that.

Is there a better alternative of doing this in RxJS that I am missing? Basically I want to emit a notification of what error has occurred, and then continue with whatever the Observable is already doing.

Share Improve this question edited Nov 24, 2015 at 16:45 Brandon 39.2k8 gold badges85 silver badges89 bronze badges asked Nov 24, 2015 at 12:11 bitspookbitspook 6697 silver badges19 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 11

This would retry failed queries:

var action$ = search$
    .flatMap(value => {
        // create an observable that will execute
        // the query each time it is subscribed
        const query = Rx.Observable.defer(() => getSearchResultsPromise(value));

        // add a retry operation to this query
        return query.retryWhen(errors$ => errors$.do(err => {
            console.log("ignoring error: ", err);
        }));
    })
    .map(payload => ({ type: "SUCCESS_ACTION", payload }));

action$.subscribe(dispatcher);

If you don't want to retry, but just want to notify or ignore errors:

var action$ = search$
    .flatMap(value => {
        // create an observable that will execute
        // the query each time it is subscribed
        const query = Rx.Observable.defer(() => getSearchResultsPromise(value));

        // add a catch clause to "ignore" the error
        return query.catch(err => {
            console.log("ignoring error: ", err);
            return Observable.empty(); // no result for this query
        }));
    })
    .map(payload => ({ type: "SUCCESS_ACTION", payload }));

action$.subscribe(dispatcher);

本文标签: javascriptRxJS catch **and** retry an ObservableStack Overflow