Как обработать два вызова API в Angular Subsink?

#javascript #node.js #angular #angular-material #mat-table

#javascript #node.js #angular #angular-материал #mat-таблица

Вопрос:

Я выполняю вызов API внутри angular subsink следующим образом:

 import {SubSink} from 'subsink';
...
...
async clickButton() {
    for (let i = 0; i < this.Id.length; i  ) {
        const hostId = await this.serviceA.Status(this.hostName[i]);
        this.subs.sink = this.serviceB.createDbEntry(hostId))
            .subscribe(s => {
                if (i === this.Id.length - 1) {
                    this.dialog.close();
                }
            });
    }
}
  

Здесь this.Id имеет тип any

Теперь я хочу выполнить еще один вызов API после успешного завершения this.serviceB.createDbEntry(hostId) И я делаю это, добавляя другой subs.subsink , как показано ниже:

 import {SubSink} from 'subsink';
...
...
async clickButton() {
    for (let i = 0; i < this.Id.length; i  ) {
        const hostId = await this.serviceA.Status(this.hostName[i]);
        this.subs.sink = this.serviceB.createDbEntry(hostId))
            .subscribe(s => {
                if (i === this.Id.length - 1) {
                    this.dialog.close();
                }
            });
        this.subs.sink = this.serviceC.runRetry(hostId))
            .subscribe(s => {
                if (i === thisserverId.length - 1) {
                    this.dialog.close();
                }
            });             
    }
}
  

Это закрывает диалоговое окно после this.serviceB.createDbEntry(hostId)) и не вызывает this.serviceC.runRetry(hostId))

Комментарии:

1. Я не знаю, что такое subsink, но попробуйте подумать о преобразовании подписки в обещание с помощью. toPromise() и просто используйте async / await

2. Проверьте switchMap оператор rxJs . Я могу добавить ответ, если вы ничего не найдете об этом.

3. Я проверяю switchMap , но также хотел бы попросить вас добавить ответ, чтобы помочь мне здесь.

Ответ №1:

С использованием наблюдаемых

Вы можете использовать forkJoin и switchMap оператор Rxjs .

Проверьте документацию forkjoin , а также

Проверьте документацию по switchMap

С помощью операторов вы можете переписать свой код следующим образом

 forkJoin(this.hostName.slice(0, this.Id.length).map(hostName => {
  return this.serviceA.Status(hostName).pipe(
    switchMap(hostId => this.serviceB.createDbEntry(hostId).pipe(map((dbEntry) => ({dbEntry, hostId})))),
    switchMap(resp => this.serviceC.runEntry(resp.hostId))
  )
})).subscribe(() => this.dialog.close());
  

С использованием обещаний

 Promise.all(this.hostName.slice(0, this.Id.length).map(hostName => 
      this.serviceA.Status(hostName)
      .then(hostId => this.serviceB.createDbEntry(hostId).then(() => hostId))
      .then(hostId => this.serviceC.runEntry(hostId))
      )).then(() => this.dialog.close())
  

Комментарии:

1. Я получаю предупреждающее сообщение Use the version that takes an array of Observables instead

2. this.Id имеет тип any . Я получаю это сообщение для forkJoin Deprecated symbol used, consult docs for better alternative устаревшей функции экспорта forkJoin<any> (источники: any): Observable<unknown[]>

3. Я также получаю сообщение об ошибке TS2339: Property 'pipe' does not exist on type 'Promise >'.

4. Почему вы используете Promises , а не Observables ? Вы не можете использовать его с promises.

5. У меня есть зависимость от использования Promises . Не могли бы вы обновить ответ для работы с Promises ? Опять же, я могу выполнить успешный первый вызов API и должен убедиться, что другой вызов API тоже работает