Existe-t-il un équivalent de 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;
}); 

Impossible de le reconstituer à partir des documents, divers articles suggèrent ForkJoin, mais ne peuvent pas le faire fonctionner ...

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'));

Pourrait simplement revenir dans le monde sain des promesses.

2
ct5845 7 mars 2016 à 18:04

3 réponses

Meilleure réponse

Rx.Observable possède une fonction toArray qui peut être utilisée pour répliquer le comportement Promise.all: il stocke toutes les valeurs émises du flux et attend que l'événement onComplete du flux sous-jacent se déclenche. Le flux résultant émettra un seul élément une fois que tous les éléments sous-jacents auront été émis:

// 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]
3
Calvin Belden 7 mars 2016 à 15:55
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 (promesse => promesse) flatMap vous aidera à résoudre la promesse sous le capot

0
Wayne Chiu 10 janv. 2017 à 09:42

Une façon un peu ringarde de le faire consiste à utiliser toPromise

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

toPromise renverra une promesse qui se résout lorsque l'observable sous-jacent se termine.

Cependant, comme la plupart des observables émettent plus d'une valeur avant la fin, les opérations telles que zip, combineLatest et withLatestFrom peuvent être plus proches de ce que vous recherchez:

Zip *: français

Chaque valeur de behavior1 est compressée avec une valeur de behavior2. Si l'une des entrées manque de valeurs, elle se bloque jusqu'à ce que cette entrée ait à nouveau une valeur.

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

Voir également: Docs, Diagramme interactif en marbre

CombineDernières

Comme zip, mais émettra une valeur chaque fois que behavior1 ou behavior2 émettra une valeur, et réutilisera la dernière valeur de l'autre observable pour l'appariement.

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

Voir également: Docs, Diagramme interactif en marbre

WithLatestFrom

Comme combineLatest, mais un seul observable détermine quand une valeur est émise.

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

Voir également: Docs, Diagramme interactif en marbre

0
qwtel 3 nov. 2017 à 15:41