Promise.all与RxJS Observables的行为?


87

在Angular 1.x中,有时我需要发出多个http请求并对所有响应进行处理。我将所有的承诺都放在一个数组中并调用Promise.all(promises).then(function (results) {...})

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

Answers:


77

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

有点超出范围,但是如果有帮助的话,关于链接承诺的主题,您可以使用简单的flatMapCf。RxJS Promise Composition(传递数据)


1
如果我有2个电话,一个返回诺言和另一个可观察到的返回我可以用户forkjoin吗?还是promise.all()?还是没有人,我必须让2个函数返回Promise或可观察的相同类型?
乔·斯莱曼

1
请帮忙,当作为参数传递的可观察对象不发出值时,forkJoin不起作用。我有空隙观测量,并仍想使用forkJoin的功能,但它不能正常工作
戈加Koreli

18

使用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!' ]

13

forkJoin也可以正常工作,但是我更喜欢CombineLatest,因为您不必担心它会占用Observable的最后一个值。这样,只要它们中的任何一个发出新值(例如,您获取某个时间间隔之类的东西),您就可以立即进行更新。


1
这不能满足我当前的需求,但是我一定会很快使用它的。
Corey Ogburn

4
这不会实现与Promise.all()相同的行为,但是与Promise.any()类似
Purrell

如果我有2个电话,一个返回诺言和另一个可观察到的返回我可以用户forkjoin吗?还是promise.all()?还是没有人,我必须让2个函数返回Promise或可观察的相同类型?
乔·斯莱曼

1
@JoeSleiman来晚了一些,但您可以站在一边:Observable.fromPromise()以及 Observable.zip()Obserable.toPromise()与Promise.all()
Arnaud P

11

reactivex.io forkJoin实际指向的邮编,这做的工作对我来说:

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

“这意味着forkJoin不会发出一次以上,并且将在此之后完成。如果您不仅需要在传递的可观察对象的生命周期结束时发出组合值,还需要在整个过程中发出组合值,请尝试使用CombineLatest或zip。rxjs-dev.firebaseapp.com/api/index/function/forkJoin
Jeffrey NicholsonCarré

2
forkJoin等待所有可观察对象结束,而zip在所有输入发出其第一个值时发出一个数组。zip可能会发出很多次。如果您有http呼叫,则没有任何区别。
hgoebl

是的,我现在变得微妙了,欢呼。我没有意识到语言部分会扩展-_-
Arnaud P
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.