Rxjs условно совершает второй http-вызов - PullRequest
0 голосов
/ 09 марта 2019

Я пытаюсь понять rxjs (6) и как мне следует вызвать условно, сделать второй пост http.

Мой сценарий таков:

  1. Я / загрузил файл.
  2. Я получаю объект, идентифицирующий текущий прогресс, и имя файла.
  3. Если текущий прогресс равен 100, я хочу сделать вторую запись http, и в случае успеха этого второго вызова вернуть прогресс и имя файла
  4. Если текущий прогресс меньше 100, просто верните прогресс и имя файла

Мой класс

export class BasePortalDetailsManagerService {
   updateCertificate(file: File): Observable<IUploadProgress> {
    return this._azureBlobStorage
               .uploadCertificateToBlobStorage2(file, this.portalKey)
               .pipe(
                  map(progress => this.mapProgress2(progress))
                );
  }

  private mapProgress2(fileProgress: FileProgress): IUploadProgress {
    if (fileProgress.Progress === 100) {
      console.log('I can do something here but there must be a better way');

    } else {
      return {
        filename: fileProgress.FilePath,
        progress: fileProgress.Progress
      };
    }
  }   
}

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

различные ссылки, на которые я перешел

Быстрый запуск rxjs

Кори Рилан

rxjs где это if / else

Ответы [ 2 ]

0 голосов
/ 10 марта 2019

Мне удалось решить мою проблему благодаря @martin, указавшему мне правильное направление.

Я изменяю mapProgress2() тип возвращаемого значения на Observable<IUploadProgress>, затем использую flatMap для выравнивания внутренней наблюдаемой.

Мои знания о rxjs очень ограничены, но я считаю, что для сценария flatMap, switchMap или concatMap будет достаточно. @martin предложил concatMap и после прочтения документов я согласен.

Из Документы RXJS

flatMap: flatMap - это псевдоним для mergeMap!

mergeMap: если вы хотите сохранить более одной внутренней подписки, попробуйте mergeMap

switchMap: если одновременно активна только одна внутренняя подписка, попробуйте switchMap

concatMap: Если важен порядок распространения и подписки внутренних наблюдаемых, попробуйте concatMap

updateCertificate(file: File): Observable<IUploadProgress> {
  return this._azureBlobStorage
             .uploadCertificateToBlobStorage2(file, this.portalKey)
             .pipe(
                flatMap(progress => this.mapProgress2(progress))
              );
}

private mapProgress2(fileProgress: IUploadProgress): Observable<IUploadProgress> {
  if (fileProgress.progress === 100) {
    return this._httpClient.post(this._portalDetails + 'certificatePath', JSON.stringify(fileProgress.filename))
               .pipe(map(res => fileProgress));
  } else {
    return Observable.create(function(observer) {
      observer.next(fileProgress);
      observer.complete();
    });
  }
}
0 голосов
/ 09 марта 2019

Вместо map используйте concatMap и в зависимости от progress верните этот исходный объект, обернутый в Observable с помощью of(progress), или верните другой Observable, который выполняет второй запрос, и сопоставьте его результат с progress:

this._azureBlobStorage.uploadCertificateToBlobStorage2(file, this.portalKey).pipe(
  concatMap(progress => progress.Progress === 100
    ? this.mapProgress2(progress).pipe(
        map(filename => ({ // This could go inside `mapProgress2` as well
          filename: progress.FilePath,
          progress: progress.Progress
        })),
      )
    : of(progress)
  ),
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...