[英]Promise in Angular 9
我正在嘗試使用 Promise 在 Angular 中編寫同步 function 調用,但它仍然得到與預期不同的結果。 我有 2 個函數使用從 API 下載數據的服務:
getData1(shortcut: string): void {
this.apiServ.getPrice(shortcut).subscribe(
(price: CurrentPrice) => {
this.price = price;
console.log(1);
},
error => this.error = error
);
}
getData2(shortcut: string): void {
this.apiServ.getPrice(shortcut).subscribe(
(price: CurrentPrice) => {
this.price = price;
console.log(2);
},
error => this.error = error
);
}
我正在嘗試在響應完成后進行下一個 function 調用。 所以:
data(shortcuts) {
this.getData1(shortcuts[0]);
this.getData2(shortcuts[1]);
}
ngOnInit() {
const myPromise = new Promise((resolve) => {
this.data(this.shortcuts);
resolve(3)
});
myPromise.then((value) => {console.log(value)});
}
但是我的瀏覽器打印了這個調用順序:
3
1
2
我究竟做錯了什么?
我也嘗試使用回調,但效果總是一樣的。
如果您想使用 Promise,您可以使用async/await ,但您可以使用 rxjs 來執行此操作。
可觀察流
我創建了兩個函數來模擬您的問題,一個稱為 getDataAsObservable 代表您的 getData 方法,另一個稱為 getDataAsPromise 代表您的 promise,然后我使用 concat ,它是 rxjs 的可觀察創建方法,它順序發出給定 Observable 的所有值然后繼續下一個。
我將 first$、second$ 和 third$ 異步函數傳遞給 concat 和訂閱,以便打印結果。
Promise流量
否則,如果你使用async/await ,你只需要等待響應。
import { Observable, concat } from 'rxjs';
import { delay } from 'rxjs/operators';
async ngOnInit() {
// first execute promise flow and wait for the response
await this.executePromiseFlow();
// after promise flow we can execute observable flow
this.executeObservableFlow();
}
executePromiseFlow = async () => {
// I use toPromise method to convert observable to a promise
const first = await this.getDataAsObservable(1).toPromise();
console.info('[Promise] output', first);
const second = await this.getDataAsObservable(2).toPromise();
console.info('[Promise] output', second);
const third = await this.getDataAsPromise(3);
console.info('[Promise] output', third);
}
executeObservableFlow = () => {
const second$ = this.getDataAsObservable(2);
const first$ = this.getDataAsObservable(1);
const third$ = this.getDataAsPromise(3);
concat(first$, second$, third$)
.subscribe((output) => console.info('[Observable] output', output))
}
getDataAsObservable = (value: number) => {
return new Observable((observer) => {
observer.next(value);
observer.complete();
}).pipe(
delay(value * 2000), // simulate HTTP request time
);
}
getDataAsPromise = (value: number) => {
return Promise.resolve(value);
}
你可以在這里閱讀更多關於 async/await 和 rxjs的信息。
您可以在 Stackblitz 上查看此內容的簡單復制
您可以使用zip
中的 zip:
從'rxjs'導入{可觀察的,zip}; 從'rxjs/operators'導入{點擊};
getData1(shortcut: string): Observable<any> {
return this.apiServ.getPrice(shortcut).pipe(
tap(
(price: CurrentPrice) => {
this.price = price;
console.log(1);
}
)
);
}
getData2(shortcut: string): Observable<any> {
return this.apiServ.getPrice(shortcut).pipe(
tap(
(price: CurrentPrice) => {
this.price = price;
console.log(2);
}
)
);
}
data(shortcuts) : Observable<any> {
const res1 = this.getData1(shortcuts[0]);
const res2 = this.getData2(shortcuts[1]);
return zip(res1, res2);
}
ngOnInit() {
this.data(this.shortcuts).subscribe(() => {
// your code
})
}
因為它們是你需要尊重它們的解決時間的承諾,這意味着等到它們完成,這意味着當你依賴它們的結果時,你不能將它們稱為正常的 function。
也因為它是一個 angular 應用程序嘗試將它們轉換為 rxjs stream from
ZC1C42145068E17A974D
getData1(shortcut: string): Observable<CurrentPrice> { // <- return stream
return this.apiServ.getPrice(shortcut).pipe(
tap(console.log, console.log), // logs emits and errors
);
}
getData2(shortcut: string): Observable<CurrentPrice> { // <- return stream
return this.apiServ.getPrice(shortcut).pipe(
tap(console.log, console.log), // logs emits and errors
);
}
data(shortcuts): Observable<[CurrentPrice, CurrentPrice]> { // <- return stream
return combineLatest([
this.getData1(shortcuts[0]),
this.getData2(shortcuts[1]),
]);
}
ngOnInit() {
const myPromise = new Promise((resolve, error) => {
// wait until completed
this.data(this.shortcuts).pipe(
take(1), // <- in promise we need just 1 emit
).subscribe(prices => resolve(prices), error);
});
myPromise.then((value) => {console.log(value)}); // profit
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.