角度5-承诺与可观察-性能上下文

时间:2019-01-17 11:54:41

标签: angular rxjs angular-observable

我有一个5号站点,该站点从REST API接收数据,类似于每页1-4对API的请求。 发生的情况是请求有时需要很长时间(有时不需要)。

现在,所有请求都使用 Observable

在一个功能中执行
return this.http.post(url, {headers: this.header})
        .map(res => res.json())      
        .catch(this.handleError)

我的问题是-是否可能由于在Observable中的使用而导致了缓慢的过程?也许 Promise 对于效果会更好? 还是在性能方面Observable和Promise之间没有区别?

5 个答案:

答案 0 :(得分:3)

根据我的测试,“承诺”比“可观察”的性能更好。

我认为Yanis-git测试是一个好的开始,但仅显示了部分图片。它仅计算Promise或Observable的开始,而不计算其解决时间。

这是我修改的代码,同时也考虑了异步函数的解析度: https://stackblitz.com/edit/typescript-xhhseh?file=index.ts

import { of, Observable, zip } from 'rxjs';
console.clear();

function testPromise(){
  console.time('promise');
  const promiseAry = [];
  for(let i = 0; i < 10000; i++) {
    promiseAry[i] = new Promise((resolve) => {
      setTimeout(() => resolve({
        name: 'promise'
      }))
    }).then(user => {
      // do something. Prefer not console.log because is ressource consuming.
    });
  }
  Promise.all(promiseAry).then(() =>{
    console.timeEnd('promise');

    // test Observables after Promises have completed
    testObservable();
  })
}

function testObservable(){
  console.time('observable');
  const observeAry = [];
  for(let i = 0; i < 10000; i++) {
    observeAry[i] = Observable.create((o) => {
      setTimeout(() => {
        o.next({
          name: 'observable'
        });
      });
    });

    observeAry[i].subscribe(user => {
      // do something. Prefer not console.log because is ressource consuming.
    });
  }
  let source$ = zip(...observeAry);
  source$.subscribe(([weatherInfo, tweetInfo]) =>
    console.timeEnd('observable')
  );

}

testPromise();

在Chrome中(在Mac上)运行测试时,直接访问此页面并打开控制台:https://typescript-xhhseh.stackblitz.io/,我得到以下结果:

promise: 279.65185546875ms
observable: 552.891845703125ms

与Firefox中非常相似的结果:

promise: 232ms - timer ended 
observable: 319ms - timer ended

反复运行它们,我总是想出Observable比Promise花费更多的时间,这尤其有意义,因为Promises现在是JavaScript的本机,而Observables并不是JavaScript的本机,因此它们似乎没有性能。

特别感谢Yanis-git提出了我分叉的原始测试。

答案 1 :(得分:1)

因为您质疑我的兴趣。我创建了相同的测试,如下所示:

console.time('observable');
for(let i = 0; i < 10000; i++) {
  let user$ = of({
    name: 'yanis-git'
  });

  user$.subscribe(user => {
    // do something. Prefer not console.log because is ressource consuming.
  });
}
console.timeEnd('observable');

console.time('promise');
for(let i = 0; i < 10000; i++) {
  new Promise((resolve) => {
    resolve({
      name: 'promise'
    });
  }).then(user => {
    // do something. Prefer not console.log because is ressource consuming.
  });
}
console.timeEnd('promise');

,结果看起来像这样(在您的浏览器/设置中可以不同,但​​是比例应该相同:

observable: 34.060791015625ms
promise: 103.4609375ms

编辑:

另一种同时具有异步特征的实现:

console.time('observable');
for(let i = 0; i < 10000; i++) {
  let user$ = Observable.create((o) => {
    setTimeout(() => {
      o.next({
        name: 'observable'
      });
    });
  });

  user$.subscribe(user => {
    // do something. Prefer not console.log because is ressource consuming.
  });
}
console.timeEnd('observable');

console.time('promise');
for(let i = 0; i < 10000; i++) {
  new Promise((resolve) => {
    setTimeout(() => resolve({
      name: 'promise'
    }))
  }).then(user => {
    // do something. Prefer not console.log because is ressource consuming.
  });
}
console.timeEnd('promise');

结果接近,但可以观察到比赛获胜。

observable: 160.162353515625ms
promise: 213.40625ms

live sample

如果要检查stackblitz,请使用真实的浏览器控制台查看计时器输出

答案 2 :(得分:0)

我正在搜索此问题并找到本文:https://netbasal.com/angular-stop-using-observable-when-you-should-use-a-promise-8da0788a8d2 我完全同意这个人。可观察的东西很棒,但是您应该在正确的地方使用它。否则,它可能是“性能杀手”。

答案 3 :(得分:0)

最后一条评论实际上不是一个公平的例子。在该方案中,更正确的用法是在此修改示例中使用RxJS:

https://stackblitz.com/edit/typescript-uajatd

有效的浏览器性能:https://typescript-uajatd.stackblitz.io

我们可以看到RxJS在竞赛中大获全胜:)

答案 4 :(得分:0)

性能故障排除的黄金法则是:始终衡量;永远不要下结论。

首先,重现页面运行缓慢的情况。检查浏览器开发者控制台中的“网络”标签。每个网络请求需要多长时间?这些请求是并行运行的,还是有阶梯式的结构,即每个请求直到上一个请求完成才开始?请求之间是否有长时间的停顿,还是在前一个请求完成后立即开始?最后一个请求完成后,页面是否立即显示已加载?

如果无法重现该问题,请考虑使用诸如sendry.io之类的监视工具来帮助收集数据。分析数据并找出花费了这么长时间的时间。您的应用程序中是否有触发该条件的记录的特定示例?

您还应该查看服务器端的应用程序日志。服务器需要多长时间来响应每个请求?

如果您需要详细了解rxjs代码在做什么,请考虑使用此工具: https://github.com/cartant/rxjs-spy

我发现这对本地发展非常有帮助。

请注意,rxjs-spy会带来较大的性能开销,并且不适合用于生产环境。