如何让 ES6 Promise 跑得更快
在前端开发中使用Promise是非常普遍的,它允许异步编程更加容易。然而,我们要注意的是,Promise并非是完美的,如果处理不当,会对性能产生非常大的影响,使网站变得缓慢。本篇文章将介绍如何优化 ES6 Promise 以提高网站性能。
- 使用
Promise.all()
和Promise.race()
Promise.all()方法接收一个Promise数组,返回一个Promise,数组中所有的Promise必须完成后Promise.all()才能完成,否则将抛出rejected。这种方案非常适合处理需要在多个未知执行时间的并发Promise同时执行的场景。
举个例子:
let p1 = new Promise(resolve => setTimeout(resolve, 2000, 'p1')) let p2 = new Promise(resolve => setTimeout(resolve, 1000, 'p2')) Promise.all([p1, p2]).then(result => console.log(result))
上面的代码将在2秒后打印['p1', 'p2']。
另一方面,Promise.race()
方法同样接收Promise数组作为参数,但返回的是最先完成的Promise。这种方案对于需要最先执行并返回的场景非常有用。
举个例子:
let p1 = new Promise(resolve => setTimeout(resolve, 2000, 'p1')) let p2 = new Promise(resolve => setTimeout(resolve, 1000, 'p2')) Promise.race([p1, p2]).then(result => console.log(result))
上面的代码将在1秒后打印‘p2’。
这两个方法可以大大提高并发执行的效率,避免等待执行时间最长的Promise阻塞其他任务。
- 避免多余的Promise
当一个值已经是Promise时,我们应该避免使用Promise包装它。这样做会产生额外的开销,并影响执行效率。正如下面的代码中的示例一样,Promise.resolve()方法接收一个Promise时,不会产生任何效果,只会浪费时间和资源。
let promiseToWrap = Promise.resolve('some value') Promise.resolve(promiseToWrap).then(value => console.log(value))
上面的代码中,我们将Promise传递给了Promise.resolve(),然后Promise会对它进行包装,最终仍然输出“some value”,但是它多了包装层。
- 使用正确的 Promise 实现
Chrome和Firefox浏览器已经为 Promise 提供原生支持,但是 Internet Explorer 11 不支持 Promise。对于还不支持 Promise 的浏览器,我们需要使用 polyfill 来支持 Promise。
在 polyfill 中,有一些 Promise 的实现比另一些更快。例如,bluebird 库的 Promise 实现比原生 Promise 更快。如果需要在老浏览器中使用 Promise,我们应该选择最快的 Promise 实现。
- 只有必要时才使用 async/await
async/await 是为了更容易的使用Promise而出现的。相比较于使用.then() ,使用 async/await 可以写出更简明和易于理解的代码。但是,async/await 有一个缺点,它会产生额外的代码和执行时间。
这意味着,对于一些简单的Promise,使用 async/await 并不划算,意味着额外的延迟和代码。它反而不如直接使用.then()。
下面是一个简单的示例,比较使用 async/await 和 .then() 的效率:
-- -------------------- ---- ------- ----- -------- ------------ - ----- ------- - ----- --------------- ----- ------- - ----- --------------- ------ ------- - -------- - -------- -------------- - ------ --------------------------- -- - ------ --------------------------- -- - ------ ------- - -------- --- --- -
可以看到,两个函数基本上是一样的,只是使用了不同的方法。然而,我们发现使用 async/await 时,有额外的执行时间,比使用 .then() 更耗时。因此,我们应该只有在必要的情况下才使用 async/await。
结论
使用Promise可以大大提高异步编程的效率。但是,在代码中正确地使用Promise并不是一件容易的事。我们需要牢记前几点的最佳实践,避免多余的Promise、使用正确的Promise实现和避免不必要的async/await。这些技巧将使我们的JavaScript代码更高效地运行。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6747c0d8555db9718d189bd0