现在,所有请求都使用 Observable :
在一个功能中执行return this.http.post(url, {headers: this.header})
.map(res => res.json())
.catch(this.handleError)
我的问题是-是否可能由于在Observable中的使用而导致了缓慢的过程?也许 Promise 对于效果会更好? 还是在性能方面Observable和Promise之间没有区别?
答案 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
如果要检查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会带来较大的性能开销,并且不适合用于生产环境。