【问题标题】:Promise.all behavior with RxJS Observables?RxJS Observables 的 Promise.all 行为?
【发布时间】: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()

【问题讨论】:

    标签: javascript angularjs rxjs observable


    【解决方案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,那没什么区别。
      • 好吧,我现在明白了,干杯。我没有意识到语言部分会扩展 -_-
      猜你喜欢
      • 2020-02-10
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      • 2020-03-20
      • 1970-01-01
      • 2023-04-09
      • 2020-04-22
      相关资源
      最近更新 更多