RXJS5 против Promise.all

Есть ли эквивалент Promise.all?

let prom1 = doA(); // some promise
let prom2 = doB(); // another promise

// wait for both promises to complete.
Promise.all([prom1, prom2], values => {
    // do something;
}); 

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

let behaviour1 = new BehaviourSubject(0);
let behaviour2 = new BehaviourSubject(1);
let allObserver = new ForkJoinObservable(behaviour1, behaviour2);

behaviour1.subscribe( () => console.log('i work'));
behaviour2.subscribe( () => console.log('i work'));
allObserver.subscribe( () => console.log('i dont work'));

Можно просто вернуться к нормальному миру обещаний.


person ct5845    schedule 07.03.2016    source источник


Ответы (3)


Rx.Observable имеет функцию toArray, которую можно использовать для репликации поведения Promise.all: она сохраняет все выдаваемые потоком значения и ожидает срабатывания события onComplete базового потока. Результирующий поток выдаст один элемент после того, как будут выданы все базовые элементы:

// Instead of Promises, we can model our async actions as observables
const operation1$ = Rx.Observable.just(1);
const operation2$ = Rx.Observable.just(2);

// Merge all our async results into a single stream
const result$ = Rx.Observable.merge(operation1$, operation2$)

// Finally, call toArray to combine all results
result$
    .toArray()
    .subscribe(x => console.log(x));
// >> [1, 2]
person Calvin Belden    schedule 07.03.2016
comment
Спасибо, попробуем! - person ct5845; 08.03.2016

import Rx, { Observable } from 'rxjs' 
import axios from 'axios'

const promiseA = axios.get('https://jsonplaceholder.typicode.com/users/1')
    , promiseB = axios.get('https://jsonplaceholder.typicode.com/users/2')

const promiseStream$ = Observable   
       .of(promiseA, promiseB)       // promises go here
       .flatMap(promise=>promise)    // resolve the promise under the hood         
       .map(response=>response.data)   
       .map(user=>user.name)   
       .subscribe(
           name=>console.log(`name is ${name}`)
           // name is Ervin Howell
           // name is Leanne Graham   
       )

flatMap(promise=>promise)

person Wayne Chiu    schedule 10.01.2017

Несколько дрянной способ сделать это - использовать toPromise

Promise.all([behaviour1.toPromise(), behaviour2.toPromise()])

toPromise вернет обещание, которое разрешается, когда базовый наблюдаемый объект завершается.

Однако, поскольку большинство наблюдаемых объектов перед завершением выдают более 1 значения, такие операции, как zip, combineLatest и withLatestFrom, могут быть ближе к тому, что вы ищете:

молния

Каждое значение поведения1 заархивировано со значением поведения2. Если на каком-либо входе заканчиваются значения, он останавливается до тех пор, пока на этом входе снова не будет значения.

Observable.zip(behavior1, behavior2)
  .subscribe(([b1, b2]) => console.log(b1, b2))

См. также: документы, Интерактивная мраморная диаграмма

комбинироватьПоследние

Подобно zip, но будет выдавать значение каждый раз, когда либо поведение1, либо поведение2 выдает значение, и будет повторно использовать последнее значение другого наблюдаемого для спаривания.

Observable.combineLatest(behavior1, behavior2)
  .subscribe(([b1, b2]) => console.log(b1, b2))

См. также: документы, Интерактивная мраморная диаграмма

withLatestFrom

Подобно combLatest, но только один наблюдаемый объект определяет, когда будет выдано значение.

behavior1.withLatestFrom(behavior2)
  .subscribe(([b1, b2]) => console.log(b1, b2))

См. также: документы, Интерактивная мраморная диаграмма

person qwtel    schedule 03.11.2017