RXJS5 对比 Promise.all

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

可能只是切换回理智的承诺世界。

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]
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) flapMap will help you to resolve promise under the hood

一种有点俗气的方法是使用 toPromise

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

toPromise 将 return 一个在底层可观察对象完成时解析的承诺。

但是,由于大多数可观察对象在完成之前会发出超过 1 个值,因此 zipcombineLatestwithLatestFrom 等操作可能更接近您要查找的内容:

zip

behavior1 的每个值都压缩为 behavior2 的值。 如果任一输入用完值,它将停止,直到该输入再次有值。

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

另请参阅:DocsInteractive marble diagram

合并最新

类似于 zip,但每次 behavior1 或 behavior2 发出一个值时都会发出一个值,并且会重用另一个可观察值的最新值进行配对。

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

另请参阅:DocsInteractive marble diagram

withLatestFrom

与 combineLatest 类似,但只有一个 observable 决定何时发出一个值。

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

另请参阅:DocsInteractive marble diagram