RxJS Observables 的 Promise.all 行为?
Posted
技术标签:
【中文标题】RxJS Observables 的 Promise.all 行为?【英文标题】:Promise.all behavior with RxJS Observables? 【发布时间】:2016-06-07 02:08:55 【问题描述】:在 Angular 1.x 中,我有时需要发出多个 http
请求并对所有响应进行处理。我会将所有的承诺放在一个数组中并调用Promise.all(promises).then(function (results) ...)
。
Angular 2 最佳实践似乎指向使用 RxJS 的 Observable
来替代 http
请求中的承诺。如果我有两个或多个从 http 请求创建的不同 Observable,是否有等效于 Promise.all()
?
【问题讨论】:
【参考方案1】:模拟Promise.all
的更直接的替代方法是使用forkJoin
运算符(它并行启动所有可观察对象并加入它们的最后一个元素):
有点超出范围,但如果有帮助,关于链接承诺的主题,您可以使用简单的flatMap
:Cf. RxJS Promise Composition (passing data)
【讨论】:
如果我有 2 个调用,一个返回承诺,另一个返回 observable,我可以使用 forkjoin 吗?或 promise.all() ?或者没有,我必须让这 2 个函数返回相同类型的 promises 或 observable? 请帮忙,当作为参数传递的可观察对象不发出值时,forkJoin 不起作用。我有 void Observables,但仍想使用 forkJoin 功能,但它不起作用【参考方案2】:使用 RxJs v6 更新 2019 年 5 月
发现其他答案很有用,并希望为 Arnaud 提供的关于 zip
用法的答案提供一个示例。
这是一个 sn-p,显示了 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!' ]
【讨论】:
【参考方案3】:forkJoin 也可以正常工作,但我更喜欢combineLatest,因为您不必担心它会占用 observables 的最后一个值。这样,只要它们中的任何一个也发出新值(例如,您按时间间隔或其他方式获取),您就可以得到更新。
【讨论】:
这不符合我目前的需求,但我肯定会很快使用它。 这并没有实现与 Promise.all() 相同的行为,但它类似于 Promise.any() 如果我有 2 个调用,一个返回承诺,另一个返回 observable,我可以使用 forkjoin 吗?或 promise.all() ?或者没有,我必须让这 2 个函数返回相同类型的 promises 或 observable? @JoeSleiman 有点晚了,但你可以选择你的立场:Observable.fromPromise() 和 Observable.zip(),或 Obserable.toPromise() 和 Promise.all()【参考方案4】:在reactivex.io forkJoin 实际上指向Zip,它为我完成了这项工作:
let subscription = Observable.zip(obs1, obs2, ...).subscribe(...);
【讨论】:
"这意味着 forkJoin 不会发出多次,并且会在之后完成。如果您不仅需要在传递的 observables 的生命周期结束时发出组合值,而且还需要在整个生命周期结束时发出组合值,请尝试combineLatest 或 zip 代替。” rxjs-dev.firebaseapp.com/api/index/function/forkJoin forkJoin 等待所有 observables 结束,而 zip 在所有输入发出它们的第一个值时发出一个数组。 zip 可能会发出很多次。如果你有 http-calls,那没什么区别。 好吧,我现在明白了,干杯。我没有意识到语言部分会扩展-_-
以上是关于RxJS Observables 的 Promise.all 行为?的主要内容,如果未能解决你的问题,请参考以下文章
Angular 6 / Rxjs - 如何基础:observables 成功,错误,最后
在 Angular2 中使用 RxJS 链接 observables
Angular RXJS Observables或Subjects在内部传递数字
Rxjs:使用 scan 或 mergeMap 或任何 rxjs 在 X 秒后将 observables 数据流(grpc 服务)组合成一个数组