RxJS sequence equivalent to promise.then()?

前端 未结 8 1354
南旧
南旧 2020-11-28 05:12

I used to develop a lot with promise and now I am moving to RxJS. The doc of RxJS doesn\'t provide a very clear example on how to move from promise chain to observer sequenc

相关标签:
8条回答
  • 2020-11-28 05:15

    RxJS sequence equivalent to promise.then()?

    For example

    function getdata1 (argument) {
            return this.http.get(url)
                .map((res: Response) => res.json());
        }
    
        function getdata2 (argument) {
            return this.http.get(url)
                .map((res: Response) => res.json());
        }
    
        getdata1.subscribe((data1: any) => {
            console.log("got data one. get data 2 now");
            getdata2.subscribe((data2: any) => {
                console.log("got data one and two here");
            });
        });
    
    0 讨论(0)
  • 2020-11-28 05:19

    For data flow (equivalent to then):

    Rx.Observable.fromPromise(...)
      .flatMap(function(result) {
       // do something
      })
      .flatMap(function(result) {
       // do something
      })
      .subscribe(function onNext(result) {
        // end of chain
      }, function onError(error) {
        // process the error
      });
    

    A promise can be converted into an observable with Rx.Observable.fromPromise.

    Some promise operators have a direct translation. For instance RSVP.all, or jQuery.when can be replaced by Rx.Observable.forkJoin.

    Keep in mind that you have a bunch of operators that allows to transform data asynchronously, and to perform tasks that you cannot or would be very hard to do with promises. Rxjs reveals all its powers with asynchronous sequences of data (sequence i.e. more than 1 asynchronous value).

    For error management, the subject is a little bit more complex.

    • there are catch and finally operators too
    • retryWhen can also help to repeat a sequence in case of error
    • you can also deal with errors in the subscriber itself with the onError function.

    For precise semantics, have a deeper look at the documentation and examples you can find on the web, or ask specific questions here.

    This would definitely be a good starting point for going deeper in error management with Rxjs : https://xgrommx.github.io/rx-book/content/getting_started_with_rxjs/creating_and_querying_observable_sequences/error_handling.html

    0 讨论(0)
  • 2020-11-28 05:20

    As far as i just found out, if you return a result in a flatMap, it converts it to an Array, even if you returned a string.

    But if you return an Observable, that observable can return a string;

    0 讨论(0)
  • 2020-11-28 05:20

    If I understood correctly, you mean consuming the values, in which case you use sbuscribe i.e.

    const arrObservable = from([1,2,3,4,5,6,7,8]);
    arrObservable.subscribe(number => console.log(num) );
    

    Additionally, you can just turn the observable to a promise using toPromise() as shown:

    arrObservable.toPromise().then()
    
    0 讨论(0)
  • 2020-11-28 05:20

    This is how I did it.

    Previously

      public fetchContacts(onCompleteFn: (response: gapi.client.Response<gapi.client.people.ListConnectionsResponse>) => void) {
        const request = gapi.client.people.people.connections.list({
          resourceName: 'people/me',
          pageSize: 100,
          personFields: 'phoneNumbers,organizations,emailAddresses,names'
        }).then(response => {
          onCompleteFn(response as gapi.client.Response<gapi.client.people.ListConnectionsResponse>);
        });
      }
    
    // caller:
    
      this.gapi.fetchContacts((rsp: gapi.client.Response<gapi.client.people.ListConnectionsResponse>) => {
          // handle rsp;
      });
    

    After(ly?)

    public fetchContacts(): Observable<gapi.client.Response<gapi.client.people.ListConnectionsResponse>> {
        return from(
          new Promise((resolve, reject) => {
            gapi.client.people.people.connections.list({
              resourceName: 'people/me',
              pageSize: 100,
              personFields: 'phoneNumbers,organizations,emailAddresses,names'
            }).then(result => {
              resolve(result);
            });
          })
        ).pipe(map((result: gapi.client.Response<gapi.client.people.ListConnectionsResponse>) => {
          return result; //map is not really required if you not changing anything in the response. you can just return the from() and caller would subscribe to it.
        }));
      }
    
    // caller
    
    this.gapi.fetchContacts().subscribe(((rsp: gapi.client.Response<gapi.client.people.ListConnectionsResponse>) => {
      // handle rsp
    }), (error) => {
      // handle error
    });
    
    0 讨论(0)
  • 2020-11-28 05:23

    A more modern alternative:

    import {from as fromPromise} from 'rxjs';
    import {catchError, flatMap} from 'rxjs/operators';
    
    fromPromise(...).pipe(
       flatMap(result => {
           // do something
       }),
       flatMap(result => {
           // do something
       }),
       flatMap(result => {
           // do something
       }),
       catchError(error => {
           // handle error
       })
    )
    

    Also note that for all this to work, you need to subscribe to this piped Observable somewhere, but I assume it's handled in some other part of the application.

    0 讨论(0)
提交回复
热议问题