我应该使用原生ES6 Promises + polyfill还是自定义Promise库?

时间:2015-10-20 07:48:03

标签: javascript promise

我想将代码切换为Promises / A + API。我的主要用途是删除回调级联

我需要一个解决方案:

  • 越可持续
  • 库大小较小
  • 原生可能性越大......

解决方案1:原生

我在caniuse http://caniuse.com/#feat=promises上看到,除了IE之外,ES6的承诺得到了很好的实现...... polyfill存在https://github.com/jakearchibald/es6-promise,因此我可以将它用于IE。

有没有人已经使用过此解决方案,是否可行?

解决方案2:外部库

我可以使用替代库,例如 Bluebird Q 。 使用它们有很大的优势吗?

更新: @sdgluck与我的第一个想法不同, Bluebird 似乎将Promise带到了更高的水平!所以我选择使用它。

2 个答案:

答案 0 :(得分:4)

可用的库

首先让我们看一下我们可以使用的最受欢迎的Promise库。

Library (minified)  | Size*  | Implementation | Native | Client        | Server
---------------------------------------------------------------------------------
native (ES6)        | 0      | Promises/A+    | Yes    | Yes           | Yes
Q                   | 2.5    | Promises/A+    | No     | Yes           | Yes
Bluebird            | 68.4   | Promises/A+    | No     | Bfy*/global   | CommonJS
when                | ?      | Promises/A+    | No     | Yes           | CommonJS
then/promise*       | 4.8    | Promises/A+    | No     | Browserify    | Yes

-

* 尺寸:缩小尺寸(KB)

* Bfy Browserify

* 注意then/promise如果支持< Bluebird则需要es5-shim IE9是必需的。 [source]

* 注意:大多数库支持在浏览器和服务器上进行初始化的多种方法(AMD,Browserify等)。这不是初始化方法的详尽列表。

______

大小

显然,使用本机ES6实现在大小方面是最具成本效益的,因为它嵌入在语言中,因此不会产生任何开销。其余的应该说明一切。具有Bluebird等额外功能的库相对较大但不足以阻止您使用它们,除非空间是主要问题。

______

可持续性

就持续发展而言,它们仍在定期维护和更新。然而,这不应该是一个主要问题,因为所有人的核心功能(或者可能更好地说他们公开的核心API )将保持不变。

就完整性而言:它们都符合Promises/A+条款。也就是说,他们将以相同的方式表现。您可以在任何这些库中使用 only 此规范给出的功能,更改您正在使用的库,并且应用程序的行为将保持不变。如果您要使用任何单个库提供的任何额外功能,则无法再进行此操作。例如,使用Bluebird的许多便捷方法意味着您的应用程序“绑定”到库中。

______

'本地岬'

如果这是一项要求,那么最适合的库将是 no library 。这当然要求您不需要支持不实现ES6 Promise规范的环境。否则,没有明显的答案。如果在环境中可用,这些库都不会使用本机Promise - 它们都实现了自己的Promise功能。您在这方面的选择归结为您认为最适合使用的API。我个人更喜欢public static void countOccurrences(Collection<String> list){ Map<String, Integer> occurrenceMap = new HashMap<String, Integer>(); Integer temp; for(String obj: list){ if((temp = occurrenceMap.put(obj, 1))!= null){ occurrenceMap.put(obj, ++temp); } } for (Map.Entry<String, Integer> entry : occurrenceMap.entrySet()) { System.out.println(entry.getKey()+" : "+entry.getValue()); } } 因为它提供了许多便利方法和promisification

______

结论

你应该使用你觉得最舒服的库。 (在我看来,无论大小。)如果你需要向后兼容性,我建议避免使用需要垫片的库,只需使用其中一个实现Promises的库。如果你需要在浏览器中运行Promises,我建议使用一个Promise库,而不是使用polyfill,因为它们提供的功能在你使用Promise时就越不可取。

答案 1 :(得分:4)

你应该使用原生承诺。

我说你是Q和Bluebird的维护者,你提到过。我说这是自2013年(开始)以来蓝鸟核心,并且多年来一直倡导蓝鸟。

我会重申这是蓝鸟核心告诉你不要在浏览器中使用蓝鸟

本机承诺的原因是:

  • 他们吞下了错误 - 如果您没有附加.catch处理程序,那么您将不知道该错误。 (这已得到修复)。
  • 他们没有显示正确的堆栈跟踪(已经修复)。
  • 他们很慢(这基本上是固定的)。

鉴于这些问题都已修复,并且所有浏览器都实现了承诺 - 您应该尽可能考虑使用本机promises和async / await而不是promise库,并根据需要调整辅助方法。

在客户端上,承诺性能无论如何都不是瓶颈 - 而且在服务器上 - 无论如何,当你看到性能问题时,bluebird是一个替代品。没有理由使用Q之类的库或何时使用。如果你填充原生承诺 - 我建议native-or-bluebird(es6-promise吞下我上次检查时的错误)。

bluebird的大多数API优势都不再相关 - 有些东西(比如.some)仍然很好,但你应该使用async/await进行流量控制

什么时候应该使用蓝鸟?

  • Old Node.js(&lt; 8)确实放慢了承诺。肯定是。
  • 真正的旧节点(&lt; 1.3)承诺吞下错误,当然。
  • 在不是Chrome的浏览器上 - 原生承诺较慢 - 所以如果你能证明它很重要。
  • 在较旧的Chrome中,以获取异步堆栈跟踪。
  • 如果您正在编写一个需要与较旧的Node.js版本兼容的库 - 当然。