DEV Community

loading...
Cover image for    Asynchronous Observables?

Asynchronous Observables?

jwp profile image John Peters ・Updated on ・2 min read

Wrapping an Observable in a Promise

The pattern...

async getSomething() {
   await new Promise((resolve, reject) => {
     let service = this.service
     service.someObservable().subscribe(
      (things) => {         
        // Tell the promise we're done
        resolve(things);
      },
      (error) => {
        console.log({Error:error});
        // Tell the promise there's an error.       
        reject(error);
      }
     );
   });
  }
Enter fullscreen mode Exit fullscreen mode

Why would we want to do this? The main reason is to gain more control on the observable. We want to hold up execution until the observable completes. Observables finish in their own time.

Ensure the Order using a closure

 this.service
   .someEvent
      // Use the async keyword here   
     .subscribe(async (newValue) => {
       // things is the closure of getSomething.
       let things = await this.getSomething();
       this.UpdateRow(newValue);
 });
Enter fullscreen mode Exit fullscreen mode

This guarantees that the call to UpdateRow never happens before the return of getSomething. Observables have execution lifecycles of their own.

Jasmine Expect using async await obserables

describe("Services", () => {
   it("should return the proper url", async () => {

      let instance = await getComponent();
      let actual = await new Promise((resolve, reject) => {
         instance.rs.getDashboardInfo().subscribe((result) => {
            resolve(result.reqParams.url === "/Dashboard/Info");
         });
      });
      expect(actual).toBe(true);
   });
});
Enter fullscreen mode Exit fullscreen mode

Another example without rejecting the Promise.

private async getPeople() {
      await new Promise((resolve, reject) => {
         // must do this to get addressibility
         let rs = this.rs; 
         rs.getPeople().subscribe(
            (people) => {
               this.people = people;
               this.setTableState();
               resolve(people);
            },
            (error) => {
               console.log("58:Ineligible People Component Error Handler");
               this.es.OpenError(ErrorModel.Create(error));
               //no reason to reject here because it's being handled
            }
         );
      });
   }
Enter fullscreen mode Exit fullscreen mode

Summary
Anytime we see a subscription we have to realize that the timing of its completion is in the hands of the V8 engine, we have no control over when it runs. We do however, have control on when the next statements run.

JWP 2020

Discussion (0)

pic
Editor guide