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?
CodePudding user response:
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).
CodePudding user response:
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();
});
});
}
CodePudding user response:
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
CodePudding user response:
Try this...
Make an promise out of it
function do(i) {
return new Promise((res) => {
this.http.getDataFromServer("api/example?id=" i).subscribe(res);
});
}