JavaScript 中的 Deferred、Promise 和 Future 之间有什么区别?

2022-08-29 23:58:13

递延、承诺和期货之间有什么区别?
这三者背后是否有普遍认可的理论?


答案 1

这些答案,包括选定的答案,对于在概念上引入承诺是有益的,但缺乏在使用库实现它们时出现的术语中究竟有什么差异的细节(并且存在重要差异)。

由于它仍然是一个不断发展的规范,因此答案目前来自尝试调查参考文献(如维基百科)和实现(如jQuery):

  • 延迟:从未在流行的参考文献中描述过,1 2 3 4,但通常被实现用作承诺决议(实现和)的仲裁者。5 6 7 resolvereject

    有时延迟也是承诺(实现),5 6其他时候,只有延迟才能解决问题,并迫使用户访问承诺使用,这被视为更纯粹。6 thenthen

  • 承诺:对于正在讨论的战略来说,这是最令人费解的词。

    一个代理对象,用于存储我们想要抽象的目标函数的同步性的结果,以及公开一个接受另一个目标函数并返回新 promise 的函数。阿拉伯数字 then

    来自 CommonJS 的示例

    > asyncComputeTheAnswerToEverything()
        .then(addTwo)
        .then(printResult);
    44
    

     

    总是在流行的参考文献中描述,尽管从未具体说明责任决议属于谁。1 2 3 4

    始终存在于流行的实现中,并且从未给出分辨率能力。5 6 7

  • 未来:在一些流行的参考文献1和至少一个流行的实现中发现了一个看似弃用的术语,8,但似乎被逐步淘汰了讨论,而不是术语“promise”3,并且并不总是在对该主题的流行介绍中提到。10

    但是,至少有一个库通常使用该术语来抽象同步性和错误处理,同时不提供功能。10 目前还不清楚避免使用“应许”这个词是否是有意为之,但这可能是一个不错的选择,因为应许是围绕着“可许的”而建立的。阿拉伯数字 then

引用

  1. 维基百科关于承诺与未来
  2. 承诺/A+规格
  3. 关于承诺的 DOM 标准
  4. DOM 标准承诺规格在制品
  5. DOJO 工具包延期
  6. jQuery Deferreds
  7. Q
  8. 未来JS
  9. 关于 Promises 的函数式 Javascript 部分
  10. AngularJS集成测试的未来

杂项可能会混淆事物


答案 2

鉴于我显然不喜欢我试图回答OP的问题。字面上的答案是,承诺是与其他对象共享的东西,而延迟的承诺应该是保密的。首先,延迟的(通常扩展承诺)可以自行解决,而承诺可能无法做到这一点。

如果您对细节感兴趣,请查看Promises/A +


据我所知,总体目的是通过标准化接口提高清晰度并松开耦合。请参阅@jfriend00中的建议阅读

与其直接将回调传递给函数(这可能导致紧密耦合的接口),不如使用 promise 来分离同步或异步代码的关注点。

就个人而言,我发现延迟在处理例如由异步请求填充的模板,加载具有依赖关系网络的脚本以及以非阻塞方式提供用户反馈以形成数据时特别有用。

实际上,比较在JS模式下异步加载CodeMirror后执行某些操作的纯回调形式(抱歉,我有一段时间没有使用jQuery了):

/* assume getScript has signature like: function (path, callback, context) 
   and listens to onload && onreadystatechange */
$(function () {
   getScript('path/to/CodeMirror', getJSMode);

   // onreadystate is not reliable for callback args.
   function getJSMode() {
       getScript('path/to/CodeMirror/mode/javascript/javascript.js', 
           ourAwesomeScript);
   };

   function ourAwesomeScript() {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   };
});

对于承诺制定的版本(再次,抱歉,我不是最新的jQuery):

/* Assume getScript returns a promise object */
$(function () {
   $.when(
       getScript('path/to/CodeMirror'),
       getScript('path/to/CodeMirror/mode/javascript/javascript.js')
   ).then(function () {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   });
});

对于半伪代码表示歉意,但我希望它使核心思想更加清晰。基本上,通过返回标准化的承诺,您可以传递承诺,从而允许更清晰的分组。