2016-02-06 5 views
13

Я пишу приложение в Angular 2, и я хочу выполнить несколько HTTP-запросов и запустить функцию для ответов.Promise .all() with RxJS

В Угловое 1, я хотел бы написать что-то вроде $q.all([$http.get(...), $http.get(...), ...]).then(doSomethingWithResponses);

Но Угловое 2 возвращается RxJS Наблюдаемые и после того, как гроздь чтения я до сих пор не могу понять, как получить ответы на несколько запросов HTTP. Как это можно сделать?

+4

Использование forkJoin, это эквивалент Promise.all –

+4

У меня есть живой образец forkJoin здесь HTTP: //www.syntaxsuccess. com/viewarticle/angular-2.0-and-http – TGH

+0

Спасибо @EricMartinez! – benshope

ответ

21

Как @ Эрик Мартинес указал, есть forkJoin. forkJoin запускает все наблюдаемые последовательности параллельно и собирает их последние элементы.

Rx.Observable.forkJoin([a,b]).subscribe(t=> { 
     var firstResult = t[0]; 
     var secondResult = t[1]; 
}); 
+2

@EricMartinez есть способ, чтобы индекс в результирующем массиве «растворялся», если Observable a или Observable b терпят неудачу (или отменены или имеют ошибку или не соответствуют условию)? Так, например, если функция Observable b не работает для data1, тогда длина результирующего массива будет равна 1 вместо двух вызовов, которые были сделаны внутри блока аргументов Observable.forkJoin (...)? –

6

Я не уверен, что вы хотели бы использовать forkJoin/zip, особенно с учетом combineLatest легче понять и будет излучать на каждом событии суб-потока, в то время как в основном forkJoin образцов на каждый подпоток излучив.

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

+1

Разница заключается в том, что вы не хотите получать уведомления о каждом испускании в каждом потоке; вам все равно, когда все потоки испускают данные. Подумайте об этом как о наблюдаемом эквиваленте 'Promise.all (обещания)' или '$ q.all (обещания)'. – GFoley83

1

Я учусь RxJS, и я пытался сделать то же самое с RxJS v5

Похоже, у нас нет forkJoin на v5 больше, так вот как я получил это работает (работает с flatMap или mergeMap, которые являются псевдонимами):

const callOne = value => 
    new window.Promise(resolve => 
     setTimeout(() => resolve(value + 10), 3000) 
    ); 

const callTwo = value => 
    new window.Promise(resolve => 
     setTimeout(() => resolve(value + 20), 1000) 
    ); 

Rx.Observable 
    .of(2) 
    .do(() => console.log('querying...')) 
    .mergeMap(number => 
     Rx.Observable.zip(
      Rx.Observable.fromPromise(callOne(number)), 
      Rx.Observable.fromPromise(callTwo(number)) 
     ) 
    ).concatAll() 
    .subscribe(createSubscriber('promises in parallel')); 
+0

Я просматриваю журнал изменений rxjs, и я ничего не вижу о том, что forkJoin устарел. Https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md – benshope

+0

@ benshope вы заставили его работать v5? Я получаю сообщение об ошибке при попытке использовать forkJoin, и я не вижу его под оператором src /. – rafaelbiten

+0

Я не пытался запустить его, но похоже, что v5 все еще находится в бета-версии. Возможно, это могло вызвать проблему. Счастливый, чтобы установить этот ответ как правильно, если forkJoin действительно ушел – benshope

2

не будет ли merge работа? Вы можете подписаться и присоединить обработчик к обратному вызову onComplete.

Я первый построить массив из моих наблюдаемых, а затем использовать статический merge:

let obs_ary: any = [obs1, obs2, obs3]; 
Observable.merge(...obs_ary);