什么时候不使用承诺

时间:2016-05-30 13:46:40

标签: javascript node.js promise es6-promise

在阅读了几篇关于es6承诺有多大以及我们为什么要实现它们的文章之后,我一直觉得 ALL 我的(非平凡的)javascript函数应该是promises。

事实上,在使用它们编写代码时我感觉很棒,因为我避免了厄运的三角形,看起来似乎得到了清晰简洁的代码。 (它确实使执行的推理变得更加简单)。

我无法找到的是:你什么时候使用承诺?我什么时候避免使用它们?

更新

虽然我已经看到了API一致性方面的一些重点,但我还没有找到一个可靠的案例。 Lux的答案表明,获取事件发射器的操作应该避免它们,因为重复的回调与promises不兼容。然而,我确实觉得答案仍然缺乏实质性的检查(正确)。

5 个答案:

答案 0 :(得分:16)

一些经验法则:

  1. 当您的方法可以同步(简单数据转换)时,请在该方法中使用同步代码。

    但是,如果该方法可以是有时,而异步有时(基于内部或外部状态的多个代码路径),则它应该是异步的 总是 即可。否则,您可能会遇到代码在复杂场景中的行为方式出现意想不到的微妙差异,因此最好避免混淆这两种态度。

    [edit]正如评论中所述,当你的方法暂时是同步的,但你坚信它可能需要在将来的某个时刻进行异步工作时,你可能希望从一开始就使用promises来避免代价高昂的重构

  2. 通常,您的API应该是一致的,因此最好在任何地方使用promises,或者在任何地方使用回调。这样可以更容易推理代码。

  3. 如果您正在编写超高性能代码和/或需要较少的内存占用,您可以考虑不使用promises而是使用回调,或使用专注于性能的promise库,例如bluebird,本机Promise实现/一般用例polyfill。

  4. [edit]无论如何,网络平台的新增内容,如全球fetch功能,返回Promise,似乎在未来的未来会有越来越多的浏览器内置版本将履行承诺。所以如果你愿意写现代代码,你就不会逃避承诺。

答案 1 :(得分:9)

您使用promises进行一次性异步操作。启动操作,执行操作,通知调用者完成或结果或错误,然后完成。

不使用承诺的情况是与上述不同的情况:

  1. 当您的操作或功能完全同步时。在同步操作上放置异步API(即使使用promises)只会使事情变得更加复杂。
  2. 代替可能多次发生的事件。例如,您不会使用按钮单击处理程序的承诺。对于重复发生的事件,eventEmitter或其他类似事件的结构仍然是更好的结构。
  3. 如果您的回调情况是回调设计为多次调用(例如报告进度或通过回调提供插件服务)。
  4. 如果您要向已经采用其他方式设计的API添加一项新操作(例如使用传统回调),则需要 API一致性
  5. 如果您定位较旧的环境本身不支持Promises(如旧浏览器),并且您尝试优化代码的下载大小,而您只做一两个异步操作,你没有使用像jQuery或Angular这样的东西,它已经有一种你可以使用的内置承诺形式。如果你正在进行任何大量的异步工作,那么很可能值得使用Promises polyfill,所以这一点仅适用于大小非常重要并且异步工作非常少的情况。
  6. 对于,其中操作通常无法完成或发生。 Promise是一个有状态的对象,因此消耗了一些内存。创建成千上万的promises来获取通常不会发生的许多不同的事情是没有意义的,因为这会产生成千上万的promise对象(通常带有随附的闭包),这些对象大部分都不会被使用。这只是低效的内存使用,并且可能通过某种事件通知更好地服务。如上所述,当您启动操作,执行操作,通知调用者结果或错误时,promise最有效。

答案 2 :(得分:6)

Well Promises有一个用例:异步结果只有一次。

如果您可以同步返回结果,则不使用Promise,并且仍然需要回调事件,因为它们可能会多次出现。

答案 3 :(得分:1)

如果您希望代码在浏览器中运行(可能没有内置Promise)并且真的很可能很重要,那么您可能决定不使用Promises,因此您无法使用承诺垫片/库。

答案 4 :(得分:1)

大多数情况下,承诺都会用于轻松完成任务。有时我们故意做一些异步的事情,以避免线程的重载,我们使用它。我们每个标签只有一个帖子。当小的东西或可以用WebWorker制作的东西时,不需要使用promises。