简体   繁体   中英

Finally on rxjs sequence gets executed on first error

I try to execute a finally statement on a Observable - sequence of http-calls.

The finally method gets executed on the first error, and not when the complete sequenze is finished.

deleteLeistungsTarife(
    leistungsTarife: Shopeinstellungen.LeistungsTarif[],
    leistungstarifGeloeschtCallback: (leistungsTarif: Shopeinstellungen.LeistungsTarif) => any) {
    let observerListe: Observable<number>[] = [];
    leistungsTarife.forEach((lt) => observerListe.push(
        this.http.delete(this._leistungenUrl + '/DeleteLeistungsTarif/' + lt.tarifLeistungId)
            .map(res => leistungstarifGeloeschtCallback(lt))
            .catch(this.handleError)                
    ));
    return Observable.forkJoin(observerListe).finally(()=>console.log("finally"));
}

the call for this method looks like this:

    this._leistungenService.deleteLeistungsTarife(
        zuLoeschendeTarife, leistungsTarif => {
            console.log("gespeichert: ", leistungsTarif)
        }
    ).subscribe(
        (r) => console.log("liste result:", r),
        (e) => console.log("liste error:", e),
        () => console.log("complete")
    )

Even there is no error, the finally and complete console-logs get hit after the first observable is finished :/

Is there an alternative function for this?

This is the expected and documented behavior of the finally function. Check the documentation .

Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.

Also by Rxjs grammar, there can only be one error emitted by an observable, which implies completion when an error occurs :

Messages sent to instances of the Observer object follow the following grammar: onNext* (onCompleted | onError)?

This grammar allows observable sequences to send any amount (0 or more) of onNext messages to the subscribed observer instance, optionally followed by a single success (onCompleted) or failure (onError) message.

The single message indicating that an observable sequence has finished ensures that consumers of the observable sequence can deterministically establish that it is safe to perform cleanup operations.

A single failure further ensures that abort semantics can be maintained for operators that work on multiple observable sequences.

To call a function only when completion of the observable, you can use two main techniques :

  • doOnCompleted
  • use materialize to treat onNext , onError , and onCompleted as regular values (and dematerialize to get the normal behavior back).

In your particular case however, I believe the approach is to:

  • catch the errors, and replace the error by an error code (ie don't throw or forcefully terminates the stream, return a value which encapsulates the error). That way the source completes normally and the forkJoin too.

I don't see the code for your handler, but I suppose it probably terminates its observable? If that's the case you could return an error code, and analyze the values of all the calls once they finish with the resultSelector parameter of forkJoin .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM