I am trying to do task step by step.
I have a for loop in a method:
async changeTimeStep3() {
for (let i = 1; i < 10; i++) {
await this.do(i)
}
}
for each step must do() task.
do(i) {
this.http
.getDataFromServer(
"api/example?id=" +i
)
.subscribe((response) => {
console.log(i);
});
}
I want to wait to get response and after response coming go to next i
But not work console.log print:
2
3
5
1
4
7
8
9
6
Note time to receive response from api is not fix.
Any help?
To get your loop print out the values in the correct order you could transform your observables into promises, so your await will block the for-loop as long as the HTTP call hasn't resolved.
import { firstValueFrom } from 'rxjs';
...
async do(i: number) {
await firstValueFrom(
this.http
.getDataFromServer(
"api/example?id=" +i
)
);
console.log(i);
}
Using firstValueFrom or lastValueFrom are the RxJS ways to get a promise as return value from an observable (since toPromise got deprecated, you can read more about that here).
You can return a Promise and use resolve() in response part of your ajax. Like:
do(i) {
return new Promise((resolve, reject) => {
this.http.getDataFromServer("api/example?id=" +i).subscribe((response) => {
resolve(response);
}, (error) => {
console.error(error);
reject();
});
});
}
The problem here is that do is not an asynchronous method; it is a synchronous method that triggers an asynchronous one. As such, the await completes immediately.
You may be able to do this:
do(i) {
return firstValueFrom(this.http
.getDataFromServer(
"api/example?id=" +i
))
}
It converts the observable into a promise and returns it. So, now the do() method returns an async object. To output from the do method; you can use a pipe:
return firstValueFrom(this.http
.getDataFromServer(
"api/example?id=" +i
).pipe(tap((result) => {console.log(i);}))
All that said, using async/await in Angular is unusual. An RXJS operator is usually considered the right approach. Possibly with concat