Rx JS Наблюдаемый результат из результата Наблюдаемого - PullRequest
0 голосов
/ 10 января 2020

У меня есть приложение Angular 8, которое использует два уровня для хранения данных: StorageService абстрагирует фактические вызовы службы HTTP, в то время как само по себе оно не содержит методов, отличных от get и save различных данных. типы.

Другие сервисы, такие как BookmarkService, используют StorageService и реализуют более сложные бизнес-логи c, такие как добавление новой статьи в закладки.

Сложность в том, что нам, возможно, придется вызвать StorageService дважды, чтобы загрузить данные и затем сохранить их.

Я хотел бы правильно раскрыть потенциальные ошибки для сайта вызывающей стороны, и мне интересно, каково будет лучшее решение для реализации чего-то подобного, без введения Rx JS объектов Subject вообще. Например, есть ли способ достичь этого с помощью простого трубопровода? Может кто-нибудь дать мне пример того, как правильно реализовать этот шаблон?

export class BookmarkService {

  constructor(private storageService: StorageService) {}

  addArticleToBookmarks(article: Article): Observable<SaveResponse> {

    this.storageService.getBookmarkedArticles().subscribe(articles =>

      articles.push(article);

      this.storageService.saveBookmarkedArticles(articles).subscribe(saveResponse => ...)

    });

    // want to return an Observable of saveResponse, if getBookmarkedArticles completed, 
    // or the error output of getBookmarkedArticles if it failed
    return ...

  }

Ответы [ 2 ]

0 голосов
/ 10 января 2020

Вы можете использовать оператор switchMap или mergeMap (также известный как flatMap).

Вот хорошее объяснение различия между ними: https://javascript.tutorialhorizon.com/2017/03/29/switchmap-vs-flatmap-rxjs/

Пример использования switchMap:

    addArticleToBookmarks(article: Article): Observable<SaveResponse> {
        return this.storageService.getBookmarkedArticles().pipe(
            switchMap(articles => {
                articles.push(article);
                return this.storageService.saveBookmarkedArticles(articles)
            })
        );
    }

Я не проверял это, но я уверен, что это будет работать

0 голосов
/ 10 января 2020

Вы имеете в виду что-то подобное?

addArticleToBookmarks(article: Article): Observable<SaveResponse> {

  this.storageService.getBookmarkedArticles()
  .pipe(
    catchError(err => console.error(err))
    switchMap(articles => {
      articles.push(article);
      return this.storageService.saveBookmarkedArticles(articles);
    }
  ).subscribe(saveResponse => ...)

}
...