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);
}
);
});
}
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);
});
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);
});
});
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
}
);
});
}
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
Top comments (0)