1

I am testing Async await in my angular application.

Here is the code:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  
  async main() {
    await this.one();
    await this.two();
    await this.three();
  }

  async one() {
    setTimeout(() => { 
      console.log('one finished');
    }, 5000);
  }

  async two() {
    setTimeout(() => { 
      console.log('two finished');
    }, 1000);
  }

  async three() {
    setTimeout(() => { 
      console.log('three finished');
    }, 4000);
  }

}

When I look into the console it's not appearing as intended.

It's appearing in order: two, three and one.

I need it to appear in order one, two and finally three.

How can I fix this?

2
  • Your one, two and three don't await their respective timeout but return immediately. You must return a promise that resolves in the callback of the timeout Commented Oct 28, 2020 at 18:58
  • 1
    Does this answer your question? How to control setTimeout with promises Commented Oct 28, 2020 at 19:00

2 Answers 2

2

This has nothing to do with Angular, this is how JavaScript works.

See this vanilla JS version:

class AppComponent  {
  async main() {
    await this.one();
    await this.two();
    await this.three();
  }

  async one() {
    setTimeout(() => { 
      console.log('one finished');
    }, 5000);
  }

  async two() {
    setTimeout(() => { 
      console.log('two finished');
    }, 1000);
  }

  async three() {
    setTimeout(() => { 
      console.log('three finished');
    }, 4000);
  }
}

let x = new AppComponent();
x.main();

I think you are expecting one() to take 5000 seconds, two() to take 1000 seconds and three() to take 4000 seconds to execute.

But Actually, they execute instantaneously, it set a timeOut and return the control flow to the caller.

Since console.logs are inside the timeOut functions, based on the timeout intervals.

You can create a setTimout function and await it on one(), two() and three()

async function setTimeouAsync(fn, ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms);
    }).then(() => {
        fn();
    });
}


@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular " + VERSION.major;

  async main() {
    await this.one();
    await this.two();
    await this.three();
  }

  async one() {
    await setTimeouAsync(() => {
      console.log("one finished");
    }, 5000);
  }

  async two() {
    await setTimeouAsync(() => {
      console.log("two finished");
    }, 1000);
  }

  async three() {
    await setTimeouAsync(() => {
      console.log("three finished");
    }, 4000);
  }

  constructor() {
    this.main();
  }
}

An example can be found HERE

Sign up to request clarification or add additional context in comments.

Comments

0

setTimeout() does not return a Promise which you can await. You would need to do the following to make it work:

timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async doSomething() {
  await timeout(5000);
  await timeout(1000);
  await timeout(3000);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.