使用RxJS Observables的Promise.all行为?

时间:2016-02-24 16:44:05

标签: javascript angularjs rxjs observable

在Angular 1.x中,我有时需要发出多个http请求并对所有响应执行某些操作。我会把所有的promises抛出一个数组并调用Promise.all(promises).then(function (results) {...})

Angular 2最佳实践似乎指向使用RxJS的Observable替代http请求中的承诺。如果我有两个或更多从http请求创建的不同Observable,它们是否等同于Promise.all()

4 个答案:

答案 0 :(得分:63)

模拟Promise.all的更直接的替代方法是使用forkJoin运算符(它并行启动所有可观察对象并加入它们的最后一个元素):

有点超出范围,但如果有帮助,关于链接承诺的主题,你可以使用简单的flatMap:Cf。 RxJS Promise Composition (passing data)

答案 1 :(得分:12)

forkJoin工作正常,但我更喜欢combineLatest,因为你不需要担心它会占用observables的最后一个值。这样,只要它们中的任何一个也发出新值,您就可以得到更新(例如,您在间隔或其他内容上获取)。

答案 2 :(得分:10)

On reactivex.io forkJoin 实际指向Zip,它为我完成了这项工作:

let subscription = Observable.zip(obs1, obs2, ...).subscribe(...);

答案 3 :(得分:2)

使用RxJs v6更新2019年5月

发现其他答案很有用,并希望为Arnaud提供的有关zip使用情况的答案提供示例。

这是一个片段,显示Promise.all和rxjs zip之间的等效性(另请注意,在rxjs6中,现在如何使用“ rxjs”而不是运算符来导入zip)。

import { zip } from "rxjs";

const the_weather = new Promise(resolve => {
  setTimeout(() => {
    resolve({ temp: 29, conditions: "Sunny with Clouds" });
  }, 2000);
});

const the_tweets = new Promise(resolve => {
  setTimeout(() => {
    resolve(["I like cake", "BBQ is good too!"]);
  }, 500);
});

// Using RxJs
let source$ = zip(the_weather, the_tweets);
source$.subscribe(([weatherInfo, tweetInfo]) =>
  console.log(weatherInfo, tweetInfo)
);

// Using ES6 Promises
Promise.all([the_weather, the_tweets]).then(responses => {
  const [weatherInfo, tweetInfo] = responses;
  console.log(weatherInfo, tweetInfo);
});

两者的输出相同。运行上面的命令可以得到:

{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]
{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]