Angular: дождитесь окончания API до 1001 *, прежде чем переходить к следующим шагам в методе, не помещая следующие шаги в функцию подписки - PullRequest
0 голосов
/ 03 апреля 2020

Как мне ждать завершения API, а затем выполнить следующий шаг в Angular с чистым кодом? Я не хочу размещать будущие шаги в рамках подписки. Есть ли способ сделать 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
    }
  });
}

Ответы [ 3 ]

1 голос
/ 03 апреля 2020

Невозможно вернуть синхронное значение из асинхронной функции, такой как let price = calculatePriceAPI();. Это идет вразрез с реактивным программированием. Одной из основных причин такого поведения является помощь в таких ситуациях, как

Как мне ждать завершения API

. Чем раньше вы его охватите, тем легче будет его использовать.

Тем не менее, один из способов - вернуть наблюдаемое из асинхронной функции. Но обратите внимание, что вам все равно нужно подписаться на него, чтобы использовать значение. Попробуйте выполнить следующее:

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();
}

Кстати, в коде есть количество отклонений.

  1. Вы присваиваете значение переменной-члену this.totalPrice. Но не использовать его при необходимости.
  2. Назначение переменной функции, такой как let price = calculatePriceAPI();, указывает на функцию. Потому что здесь вывод асинхронный, и вы не можете вернуть из него синхронные данные. См. здесь для получения информации об асинхронных запросах.
  3. Функции-члены должны указываться ключевым словом this. Он отсутствует в let price = calculatePriceAPI();.
  4. . Как отмечает @amakhrov в комментариях, в этом конкретном c случае функция calculatePriceAPI() не слишком эффективна. Первичная подписка может быть выполнена непосредственно в родительской функции.
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 голосов
/ 03 апреля 2020

То, что вы могли бы сделать, это вместо работы с Observables здесь, работать с Promises, так как они могут быть объединены с async / await, который обеспечивает синхронный поток кода.

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();
}

Обратите внимание на asyn c в сигнатуре метода, которая сигнализирует, что эта функция выполняет асинхронную связь и позволяет использовать ключевое слово await внутри. Await убедится, что Обещание выполнено, прежде чем перейти к следующей строке. Это снова должно казаться очень естественным, поскольку теперь это в основном синхронный код.

Однако в большинстве случаев вам будет хорошо без async / await и в полной мере используйте Obserables и асинхронную связь в целом.

Найдите приведенный ниже пример:

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

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

Из вашего API просто верните Observable, чтобы ваш код мог реагировать на него с его подписью. Затем, в рамках этой подписки, вы можете использовать цену и записать что-то на консоль, как только все будет закончено.

0 голосов
/ 03 апреля 2020

Вы можете использовать async await.

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

Без асинхронного ожидания c, консольный журнал будет показан немедленно. Использование асин c кода ожидания ожидает завершения асин c кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...