Дождитесь завершения нескольких http-запросов, прежде чем запускать функцию в angular - PullRequest
2 голосов
/ 25 апреля 2019

У меня есть несколько сообщений http, которые извлекают данные JSON из базы данных MySQL.Я хочу, чтобы функция прослушала их все и выполнила следующий фрагмент кода, как только все они вернут, что данные получены.

Я пробовал несколько вариантов асинхронизации с ожиданием, но функция не 'Кажется, я жду, пока не завершится публикация HTTP.

У меня есть служба риска.этот код:

getRiskTable():any {
    return this.riskService.getRiskTable().subscribe(
      (res: []) => {
        this.riskTable = res; // the value is correctly captured here
        return true;
      },
      (err) => {
        this.error = err;
      }
    );
  }

А затем асинхронная функция, которая запускает несколько из этих функций, теоретически предполагается, что все функции завершатся, и затем записать значение.Но по какой-то причине глобальная переменная this.riskTable не определена в этой функции.

async getAllData(){
    let riskTable = await this.getRiskTable();
    let risks = await this.getAllRisks();

    console.log(riskTable); //This returns stuff
    console.log(risks);
    console.log(this.riskTable); //This returns undefined even though it was set in getRiskTable
  }

Пожалуйста, любые указатели - я очень плохо знаком с угловатым, и сложность этого делает меня полностью озадаченным.2 дня и 100-кратные вариации, чтобы заставить это работать Я медленно теряю свои бананы!

Ответы [ 3 ]

1 голос
/ 25 апреля 2019

Прежде всего, ключевые слова async / await предназначены для использования с обещаниями, а не Observable с.Таким образом, вы можете преобразовать наблюдаемое в обещание, используя toPromise(), или вы можете использовать rxjs ForkJoin .Вам также нужно изменить методы, чтобы они возвращали наблюдаемое или возвращали обещание, вы не можете ничего сделать с подпиской, которую subscribe возвращает при вызове, и это то, что вы сейчас передаете от getRiskTable.

Еще одна проблема заключается в том, что вы не пользуетесь системой типов, не используйте any везде, потому что эти ошибки могли быть обнаружены во время переноса, и теперь вы должны догадаться, почему во время выполнения происходит сбой.сложнее.

import { forkJoin } from 'rxjs';
import { shareReplay } from 'rxjs/operators';

getRiskTable() : Observable<Risk[]> {
  const tableObservable = this.riskService.getRiskTable().pipe(shareReplay());
  tableObservable.subscribe((res) => this.riskTable = res, (err) => {this.error = err;});
  return tableObservable;
}

getAllData() {
  let riskTable = this.getRiskTable();
  let risks = this.getAllRisks(); // should also return some observable

  forkJoin(riskTable, risks).subscribe(_ => {
    // all observables have been completed
  });
}

Обратите внимание, что я также добавил shareReplay, который гарантирует, что несколько подписок на одну и ту же наблюдаемую страницу не приведут к нескольким вызовам к конечной точке API.Один результат распределяется между несколькими подписками на наблюдаемое.

1 голос
/ 25 апреля 2019

Поскольку вы используете Angular, вы должны использовать RxJS forkJoin , чтобы объединить наблюдаемые из обоих методов запроса API в одно наблюдаемое значение и вернуть значения , подписав на Это.

Не забудьте импортировать forkJoin в ваш компонент.

import { forkJoin } from 'rxjs';

..

getAllData(){
  const riskTable = this.riskService.getRiskTable();
  const risks = this.riskService.getAllRisk();

  forkJoin(riskTable, risks).subscribe(response => { 
    console.log(response);
  })
}

Если вы настаиваете на том, чтобы обрабатывать его как Обещание, а не как Обсерваторию, вы можете использовать Promise.all () , который возвращает их как одно Обещание.

0 голосов
/ 25 апреля 2019

ваша первая функция getRisk возвращает наблюдаемое, а не обещание, вам нужно сделать .toPromise () для преобразования вашего наблюдаемого в обещание. ваша вторая функция getRiskTable подписала observable, что очень противоречиво по сравнению с вашей первой, вы должны сделать то же самое, так как ваша первая функция только возвращает обещание, тогда ваша асинхронная очередь должна работать.

или вы можете использовать forkjoin (obs1, obs2), в зависимости от ваших интересов, но оставайтесь последовательными.

...