Promise.all () с использованием RxJs.Observable - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь реализовать эквивалент Promise.all, используя RxJs Observable в angular 5, уже перепробовал все предложенные решения здесь , но ни одно из них не сработало для меня, запросы http в цепочке просто не выполнялись.

Вот код, который я пытаюсь выполнить:

let selected = [{channel: 1},{channel: 2},{channel: 3}];

postToDB(item: any): Observable<any> {
   return this.http.post('/api/items/', item);
}

submitAll() {
   let submitAllSelected = selected.map((item: any) => {
      return this.postToDB(item).map((res: Response) => res.json());
   });

  Observable.forkJoin(submitAllSelected)
    .subscribe((result: any) => {
      this.toaster.success('item saved successfully');
    }, (err: any) => {
      this.toaster.error(JSON.stringify(err));
    }, () => {
     this.toaster.success('All items saved successfully');
    });

}

По какой-то причине, и я не могу выяснить, http-запрос не запускается, после submitAll ()вызывается и обратный вызов подписки не вызывается.Единственный способ, которым мне удалось это сделать, - это добавить .subscribe (cb) или.toPromise () после функции postToDB ().

Этот подход хорошо работает с:

Promise.all(selected.map(item => postToDB(item).toPromise()).then(//do something);

Но не с Observable.forkJoin / zip / concat или любыми другими методами, которые я пробовал.Будет здорово, если кто-то укажет мне, где я ошибся.

1 Ответ

0 голосов
/ 26 апреля 2018

Проблема была там:

let submitAllSelected = selected.map((item: any) => {
      return this.postToDB(item).map((res: Response) => res.json());
});

submitAllSelected имеет тип Observable<Promise<any>>[]. Это должно быть Observable<any>[]

Правильный путь:

let submitAllSelected = this.selected.map((item: any) => {
      return this.postToDB(item).pipe(map(data => data))
});

Если вы используете HttpClient, нет необходимости преобразовывать ответ в json.

Демонстрация StackBlitz

...