Angular 5 - Promise 与 Observable - 性能上下文

lev*_*evi 6 rxjs angular angular-observable

我有一个 Angular 5 站点,它从 REST API 接收数据,例如每个页面向 API 发出 1-4 个请求,发生的情况是请求有时需要很长时间(有时不需要)。

现在,所有请求都使用Observable在一个函数中执行:

return this.http.post(url, {headers: this.header})
        .map(res => res.json())      
        .catch(this.handleError)
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 是否因为正在使用 Observable 而导致缓慢的过程发生?会承诺将是更好的性能?或者在性能上下文中 Observable 和 Promise 之间没有区别吗?

Uni*_*nic 5

根据我的测试,Promise 比 Observable 的性能更高。

我认为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();
Run Code Online (Sandbox Code Playgroud)

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

promise: 279.65185546875ms
observable: 552.891845703125ms
Run Code Online (Sandbox Code Playgroud)

Firefox 中的结果非常相似:

promise: 232ms - timer ended 
observable: 319ms - timer ended
Run Code Online (Sandbox Code Playgroud)

反复运行它们,我总是发现 Observable 比 Promise 花费更多的时间,这是有道理的,特别是因为 Promise 现在是 JavaScript 原生的,而 Observable 不是,所以它们看起来性能不那么好。

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


Yan*_*git 4

因为你的问题引起了我的兴趣。我创建了相同的测试,如下所示:

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');
Run Code Online (Sandbox Code Playgroud)

结果看起来像这样(您的浏览器/设置可能有所不同,但比例应该相同:

observable: 34.060791015625ms
promise: 103.4609375ms
Run Code Online (Sandbox Code Playgroud)

编辑 :

另一个带有异步特征的实现:

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');
Run Code Online (Sandbox Code Playgroud)

结果很接近,但比赛是可观察到的胜利。

observable: 160.162353515625ms
promise: 213.40625ms
Run Code Online (Sandbox Code Playgroud)

现场样品

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

  • 代码片段中的承诺将异步解析(作为微任务),而可观察量是同步的,因此这里进行的比较是不合理的。 (6认同)