Dynami c массив наблюдаемых, запускаемых последовательно с функцией switchMap, запускаемой после того, как все завершено, даже если некоторые из них не работают - PullRequest
1 голос
/ 04 августа 2020
• 1000 false), эта функция должна работать, даже если некоторые или все наблюдаемые вышли из строя.

В настоящее время у меня есть следующее, но похоже, что это не работает:

updateOfflineJobs(): Observable<boolean> {

return this.jobsLocal.getOfflineJobIds().pipe(
  switchMap(jobIds => {

      // Create array of observables to update each offline job
      const observableArray: Observable<any>[] = [];
      jobIds.forEach(jobId => {
         observableArray.push(this.updateJob(jobId, appUser));
      });

      return from(observableArray).pipe(
        concatAll()).pipe(
          switchMap(() => {
            // Check offline jobs again to make sure none still dirty
            return this.jobsLocal.getOfflineJobIds();
          }),
          map(stillDirtyJobIds => {

            return stillDirtyJobIds.length === 0;
          }),
      );
    }
  }),
  catchError(e => {
    return of(false);
  })
);
}

1 Ответ

0 голосов
/ 04 августа 2020

Вы почти у цели. Вместо того, чтобы связать центральный catchError в конце, вы можете передать каждому наблюдаемому в массиве его собственные обработчики ошибок. И из обработчиков ошибок верните наблюдаемое, которое не запускает обратный вызов error подписки (я использую константу Rx JS EMPTY).

Попробуйте следующее

import { EMPTY, ... } from 'rxjs';

updateOfflineJobs(): Observable <boolean> {
  return this.jobsLocal.getOfflineJobIds().pipe(
    switchMap(jobIds => {
      const observableArray: Observable <any> [] = [];
      jobIds.forEach(jobId => {
        observableArray.push(
          this.updateJob(jobId, appUser).pipe(
            catchError(error => {                  // <-- each observable has it's own error handler
              // handle error
              return EMPTY;
            })
          )
        );
      });

      return from(observableArray).pipe(
        concatAll(),
        switchMap(_ => this.jobsLocal.getOfflineJobIds()),
        map(stillDirtyJobIds => stillDirtyJobIds.length === 0),
        catchError(e => {
          return of(false);
        })
      )
    })
  );
}
...