何时不使用承诺
在阅读了许多关于es6的承诺以及为什么要实现这些承诺的文章之后,我感到所有的(不重要的)javascript函数都应该是承诺的。
事实上,使用它们编写代码让我感觉很好,因为我避免了厄运的三angular形,并且看起来变得简洁明了。 (这真的使得关于执行的推理更简单)。
我没能find的是:什么时候不使用承诺? 我何时避免使用它们?
更新:
虽然我已经看到一些像API一致性的伟大点,我还没有find坚实的NO情况。 Lux的答案表明,获取事件发射器的操作应避免它们,因为反复出现的callback与promise不兼容。 不过,我觉得答案现在仍然缺乏实质性的检查(正确)。
一些经验法则:
-
当你的方法可以是同步的(简单的数据转换),那么在那个方法中使用同步代码。
但是,如果方法有时可能是同步的, 有时是asynchronous的(基于内部或外部状态的多个代码path),它应该总是asynchronous的。 否则,在复杂的情况下,您的代码的行为可能会出现意外的细微差异,所以最好避免混淆这两种态度。
正如评论中指出的那样,当你的方法现在是同步的时候,但你坚信它可能需要在将来的某个时候做asynchronous工作,你可能想从一开始就使用promise来避免代价高昂的重构。
-
一般来说,你的API应该是一致的,所以最好是在任何地方使用promise,或者在任何地方callback。 这将使得更容易推理代码。
-
如果您正在编写超高性能代码和/或需要较less的内存占用空间,那么可以考虑不使用promises,而是使用callback函数,或者使用一个关注性能的promise库,比如bluebird ,而不是原生的Promise实现/一般用例polyfill 。
-
无论如何,networking平台的新增function(如全局获取function)会返回一个
Promise
,而且在未来的将来,似乎越来越多的浏览器插件将按照承诺进行操作。 所以,如果你愿意写现代的代码,你不会逃避承诺。
您使用承诺进行一次性asynchronous操作。 开始操作,执行操作,通知呼叫者完成或结果或错误,然后做好。
不使用承诺的情况是与上述不同的情况:
- 当你的操作或function是完全同步的 。 在asynchronous操作上放置一个asynchronousAPI(甚至是承诺)只会使事情比需要更复杂。
- 代替多次发生的事件 。 例如,你不会使用button点击处理程序的承诺。 事件发射器或其他类似事件的结构对于重复事件仍然是更好的结构。
- 当您有callback的情况下,callback被devise为被多次调用 (如报告进度或通过callback提供插件服务)。
- 如果您将一个新的操作添加到已经以其他方式devise的API(例如使用传统的callback),并且需要API一致性 。
- 如果你的目标是那些本不支持Promise的老式环境 (比如老式的浏览器),而你正试图优化下载代码的大小,而你只做一两个asynchronous操作, jQuery或Angular已经有了一个可以使用的内置promise的forms。 如果您正在进行大量的asynchronous工作,那么使用Promises聚合填充很有可能是值得的,所以这一点仅适用于大小非常重要,而且asynchronous工作非常less的情况。
- 行动往往没有完成或发生的情况 。 承诺是一个有状态的对象,因此消耗一些记忆。 创build数以千计的承诺是没有意义的,以获得通常不会发生的许多不同事情的通知,因为这会创build成千上万的承诺对象(通常伴随着closures),而这些承诺对象通常不会被使用。 这只是低效率的内存使用情况,可能更适合某种事件通知。 正如我上面所说的,当您启动一个操作,执行操作,通知调用者结果或错误时,promise最有效。
那么承诺有一个用例:asynchronous结果,只有一次。
如果可以同步返回结果,则不使用Promises,并且仍然需要callback事件,因为它们可能会多次出现。
如果你希望你的代码在浏览器中运行(可能没有内置的Promise)并且大小真的很重要,你可以决定不使用Promise,所以你不能使用Promise shims / libs。
大多数的承诺都习惯于与不同的任务一起工作。 有时我们故意做一些事情是asynchronous的,以避免重载线程,我们的工作。 我们每个标签只有一个线程。 当WebWorker可以做的事情很小或者事情的时候,不需要使用promise。