簡體   English   中英

Angular 9 中的 Promise

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM