2

Can i use the async with await like this? Am i killing the async/await here? The code below is working without error, I know that the async/await only works with Promise<T>. My getItem is an Observable. Thanks.

roleService.getItem({ page: p.pageIndex + 1, pageSize: p.pageSize })
.takeUntil(this.unsubscribe$)
.map((res: ResponseDto) => <DtoModel>res.contentBody)
.do(async (dto: DtoModel) => await this.subject.next(dto.content)) // working wihtout error
.subscribe(async (dto: DtoModel) => await (this.pager = dto.pager), //working without error
          (error: any) => Observable.throw(error));
Robin
  • 605
  • 7
  • 28

1 Answers1

2

You can use the async functions the way you do but it will have no effect in your example. You have to understand that async function returns a promise:

const fn = async function() {};
fn() instanceof Promise

So if you use it in the observable chain you will receive a promise:

interval(500)
  .first()
  .map(async (v) => {
    return v;
  })
  .subscribe((v) => {
    console.log(v instanceof Promise); // logs `true`
  });

The way you constructed your example it won't have any effect on the observables chain because output from do operator is ignored and there's no listener for the output from the subscribe callback. So basically there's no reason to use async there.

If you wanted instead to wait until async function resolves and get the results of that function use mergeMap operator:

interval(500)
  .first()
  .map(async (v) => {
    return v;
  })
  .mergeMap((p) => {
    return p;
  })
  .subscribe((v) => {
    console.log(v);
  });
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • So how do i wait this `do((dto: DtoModel) => this.subject.next(dto.content))` before subscribe statement? I have `TODO` with that subject. I don't know how much time it takes to complete so i can't chain with `.delay(...)` Is there a better way to wait until the first statement complete before next? Thanks. – Robin Jul 25 '17 at 13:29
  • why do you want to wait for it? does it return any value? – Max Koretskyi Jul 25 '17 at 13:39
  • It does not return anything. The subject send the new value from `do(...)` where the subject is subscribed to angular component for data changes on template. So i have to wait until angular scan and complete from `changeDetecoterRef`. My component change detection strategy is in default. If i chain with `.delay(..)` then the second statement value is bound to angular but if i remove, the second value is not applied. – Robin Jul 25 '17 at 13:57
  • @Robin, sorry, I don't understand. What is unclear about my answer? – Max Koretskyi Jul 25 '17 at 14:53
  • **@Maximus** I understood your answer's example above, but my problem isn't resolved. I mean how to tell the angular change detection that `foo[]` being process while `bar[]` is updated and rendering in view? Wait till `foo[]` & `bar[]` to complete and then start rendering to the view/component etc. Like if i have `
    ` & `
    0 && getFromBar(f.id)">` so how do i chain and do synchronously? Thanks.
    – Robin Jul 25 '17 at 15:20
  • @Robin, this question is **completely different** than the one you posted. Update the question with every details – Max Koretskyi Jul 25 '17 at 15:28
  • **Maximus** I will ask another question with details. The answer you wrote for this question is correct. Thanks. – Robin Jul 25 '17 at 15:40