Jak czekać na ukończenie API, a następnie wykonać następny krok w Angular z czystym kodem? Nie chcę umieszczać przyszłych kroków w subskrypcji. Czy istnieje sposób, aby najpierw uzupełnić interfejs API?

public overallMasterFunction(){
    executeMemberSetup();
    let price = calculatePriceAPI();  // Wait for this API line to complete, and conduct further steps
    let totalAmount = price * this.quantity;
    console.log('Sales Completed')
}

calculatePriceAPI(){
  this.customerSalesProxy.getPrice().subscribe(res => {
    if (res?.totalPrice) {
      this.totalPrice = res.totalPrice
    }
  });
}
-1
user12425844 3 kwiecień 2020, 08:42

3 odpowiedzi

Najlepsza odpowiedź

Nie możesz zwrócić wartości synchronicznej z funkcji asynchronicznej, takiej jak let price = calculatePriceAPI();. Jest to sprzeczne z programowaniem reaktywnym. Jednym z głównych powodów takiego zachowania jest pomoc w sytuacjach takich jak

Jak czekać na ukończenie interfejsu API

. Im szybciej go obejmiesz, tym łatwiej będzie z niego korzystać.

To powiedziawszy, jednym ze sposobów byłoby zwrócenie obserwowalnej funkcji asynchronicznej. Pamiętaj jednak, że nadal musisz ją subskrybować, aby używać tej wartości. Spróbuj wykonać następujące czynności

public overallMasterFunction(){
    executeMemberSetup();
    let totalAmount: any;
    this.calculatePriceAPI().subscribe(
      price => { totalAmount = price * this.quantity; }
    );
    console.log('Sales Completed');
}

calculatePriceAPI(){
  const result = new Subject<any>();

  this.customerSalesProxy.getPrice().subscribe(res => {
    if (res.totalPrice) {
      this.totalPrice = res.totalPrice;
      result.next(res.totalPrice);
    }
  });

  return result.asObservable();
}

BTW jest wiele nieprawidłowości w kodzie.

  1. Przypisujesz wartość do zmiennej składowej this.totalPrice. Jednak nie używam go w razie potrzeby.
  2. Przypisanie zmiennej do funkcji, takiej jak let price = calculatePriceAPI();, wskazuje na funkcję. Ponieważ tutaj dane wyjściowe są asynchroniczne i nie można zwrócić z nich danych synchronicznych. Zobacz tutaj, aby uzyskać informacje o żądaniach asynchronicznych.
  3. Do funkcji składowych należy odwoływać się za pomocą słowa kluczowego this. Brakuje w let price = calculatePriceAPI();.
  4. Jak zauważył @amakhrov w komentarzach, w tym konkretnym przypadku funkcja calculatePriceAPI() nie robi dużo. Podstawową subskrypcję można wykonać bezpośrednio w funkcji nadrzędnej.
public overallMasterFunction(): Observable<any> {
    const result = new Subject<any>();
    let totalAmount: any;

    executeMemberSetup();
    this.customerSalesProxy.getPrice().subscribe(res => {
      if (res.totalPrice) {
        this.totalPrice = res.totalPrice;
        totalAmount = res.totalPrice * this.quantity;
        result.next(totalAmount);
      }
    });
    console.log('Sales Completed');

    return result.asObservable();
}
0
Michael D 3 kwiecień 2020, 06:19

Możesz użyć async await.

async ngOnInit() {
    await new Promise(resolve => setTimeout(resolve, 5000));
    console.log('Done!');
}

Bez oczekiwania asynchronicznego dziennik konsoli byłby wyświetlany natychmiast. Korzystanie z kodu async await czeka na zakończenie kodu asynchronicznego.

0
Carsten 3 kwiecień 2020, 05:54

Zamiast pracować z Observables tutaj, możesz pracować z Promises, ponieważ można je łączyć z async / await, co umożliwia synchroniczny przepływ kodu.

public async overallMasterFunction(){
    executeMemberSetup();
    let price = await calculatePriceAPI();  // Wait for this API line to complete, and conduct further steps
    let totalAmount = price * this.quantity;
    console.log('Sales Completed')
}

calculatePriceAPI(): Promise<any> {
  return this.customerSalesProxy.getPrice().toPromise();
}

Zwróć uwagę na async w sygnaturze metody, która sygnalizuje, że ta funkcja wykonuje komunikację asynchroniczną i pozwala na użycie słowa kluczowego await wewnątrz. Oczekiwanie upewni się, że Obietnica została rozwiązana przed przejściem do następnej linii. Powinno to znów wydawać się bardzo naturalne, ponieważ jest to teraz zasadniczo kod synchroniczny.

Jednak w większości przypadków powinieneś być w porządku bez async / await i w pełni korzystać z Observables i ogólnie komunikacji asynchronicznej.

Znajdź przykład poniżej:

public overallMasterFunction(){
    executeMemberSetup();
    let price = calculatePriceAPI().subscribe(price => {
        let totalAmount = price * this.quantity;
        console.log('Sales Completed')
    });
}

calculatePriceAPI(): Observable<any> {
  this.customerSalesProxy.getPrice();
}

Z twojego API, po prostu zwróć Observable, aby twój kod mógł na nie zareagować poprzez zasubskrybowanie. Następnie w ramach tej subskrypcji możesz użyć ceny i zalogować coś do konsoli, gdy wszystko zostanie ukończone.

0
gerstams 3 kwiecień 2020, 06:47