本文翻译自:What are the differences between Deferred, Promise and Future in JavaScript?
What are the differences between Deferreds, Promises and Futures? 递延,承诺和期货之间有什么区别?
Is there a generally approved theory behind all these three? 这三者之间是否有公认的理论?
#1楼
参考:https://stackoom.com/question/SXK7/JavaScript中的Deferred-Promise和Future之间有什么区别
#2楼
What really made it all click for me was this presentation by Domenic Denicola. 真正使这一切单击对我来说是这样介绍的Domenic Denicola。
In a github gist , he gave the description I like most, it's very concise: 在github要点中 ,他给出了我最喜欢的描述,这非常简洁:
The point of promises is to give us back functional composition and error bubbling in the async world. 许诺的目的是使我们在异步世界中恢复功能组合和错误冒泡。
In other word, promises are a way that lets us write asynchronous code that is almost as easy to write as if it was synchronous . 换句话说,承诺是一种方式,让我们写异步代码几乎是一样容易写,如果它是同步的 。
Consider this example, with promises: 考虑以下示例,并附带以下承诺:
getTweetsFor("domenic") // promise-returning async function
.then(function (tweets) {
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
})
.then(doHttpRequest) // promise-returning async function
.then(
function (responseBody) {
console.log("Most recent link text:", responseBody);
},
function (error) {
console.error("Error with the twitterverse:", error);
}
);
It works as if you were writing this synchronous code: 就像您正在编写此同步代码一样:
try {
var tweets = getTweetsFor("domenic"); // blocking
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
console.log("Most recent link text:", responseBody);
} catch (error) {
console.error("Error with the twitterverse: ", error);
}
(If this still sounds complicated, watch that presentation!) (如果这听起来仍然很复杂,请观看该演示!)
Regarding Deferred, it's a way to .resolve()
or .reject()
promises. 关于Deferred,这是实现.resolve()
或.reject()
.resolve()
的一种方法。 In the Promises/B spec, it is called .defer()
. 在Promises / B规范中,它称为.defer()
。 In jQuery, it's $.Deferred()
. 在jQuery中,它是$.Deferred()
。
Please note that, as far as I know, the Promise implementation in jQuery is broken (see that gist), at least as of jQuery 1.8.2. 请注意,据我所知,至少在jQuery 1.8.2中,jQuery中的Promise实现已损坏(请参见要点)。
It supposedly implements Promises/A thenables , but you don't get the correct error handling you should, in the sense that the whole "async try/catch" functionality won't work. 它据说实现了Promises / A thenables ,但是在整个“异步try / catch”功能无法正常工作的意义上,您没有获得应有的正确错误处理。 Which is a pity, because having a "try/catch" with async code is utterly cool. 遗憾的是,因为使用异步代码进行“尝试/捕获”非常酷。
If you are going to use Promises (you should try them out with your own code!), use Kris Kowal's Q . 如果您要使用Promises(您应该使用自己的代码进行尝试!),请使用Kris Kowal的Q。 The jQuery version is just some callback aggregator for writing cleaner jQuery code, but misses the point. jQuery版本只是用于编写更简洁的jQuery代码的一些回调聚合器,但没有指出重点。
Regarding Future, I have no idea, I haven't seen that in any API. 关于Future,我不知道,在任何API中都没有看到。
Edit: Domenic Denicola's youtube talk on Promises from @Farm 's comment below. 编辑: Domenic Denicola在youtube上关于 @Prom在下面的评论中的承诺的演讲 。
A quote from Michael Jackson (yes, Michael Jackson ) from the video: 视频中迈克尔·杰克逊( Michael Jackson )的话:
I want you to burn this phrase in your mind: A promise is an asynchronous value . 我希望您能记住这句话: 诺言是异步值 。
This is an excellent description: a promise is like a variable from the future - a first-class reference to something that, at some point, will exist (or happen). 这是一个很好的描述:一个承诺就像来自未来的变量-对某个事物在某些时候将存在(或发生)的一流参考。
#3楼
These answers, including the selected answer, are good for introducing promises conceptually, but lacking in specifics of what exactly the differences are in the terminology that arises when using libraries implementing them (and there are important differences). 这些答案,包括所选择的答案,是良好的概念引入的承诺,但在细节缺乏究竟差别在使用图书馆实现它们(也有重要的差别)时出现的术语。
Since it is still an evolving spec , the answer currently comes from attempting to survey both references (like wikipedia ) and implementations (like jQuery ): 由于它仍然是一个不断发展的规范 ,当前的答案来自尝试调查参考(例如Wikipedia )和实现(例如jQuery ):
Deferred : Never described in popular references, 1 2 3 4 but commonly used by implementations as the arbiter of promise resolution (implementing
resolve
andreject
). 递延的 :从未在流行的参考文献1 2 3 4中描述过,但通常由实现用作承诺解决方案的仲裁者(实现resolve
和reject
)。 5 6 7 5 6 7Sometimes deferreds are also promises (implementing
then
), 5 6 other times it's seen as more pure to have the Deferred only capable of resolution, and forcing the user to access the promise for usingthen
. 有时,递延也是promise(then
实现),在其他5到 6次看来,只有Deferred才具有解析能力,并迫使用户访问使用then
的promise更为纯粹。 7 7Promise : The most all-encompasing word for the strategy under discussion. 承诺 :正在讨论的策略中最引人入胜的词。
A proxy object storing the result of a target function whose synchronicity we would like to abstract, plus exposing a
then
function accepting another target function and returning a new promise. 一个代理对象,它存储目标函数的结果,我们希望对其进行抽象化,并公开一个then
函数,该函数接受另一个目标函数并返回新的promise。 2 2Example from CommonJS : 来自CommonJS的示例:
> asyncComputeTheAnswerToEverything() .then(addTwo) .then(printResult); 44
Always described in popular references, although never specified as to whose responsibility resolution falls to. 始终在大众参考文献中进行描述,尽管从未明确说明其责任解决方案属于谁。 1 2 3 4 1 2 3 4
Always present in popular implementations, and never given resolution abilites. 始终存在于流行的实现中,并且从未提供解决方案的能力。 5 6 7 5 6 7
Future : a seemingly deprecated term found in some popular references 1 and at least one popular implementation, 8 but seemingly being phased out of discussion in preference for the term 'promise' 3 and not always mentioned in popular introductions to the topic. 未来 :在一些流行的参考文献1和至少一个流行的实现8中似乎已经过时的术语,但似乎优先于术语“承诺” 3而逐步退出讨论,并且在该主题的引言中并不总是提及。 9 9
However, at least one library uses the term generically for abstracting synchronicity and error handling, while not providing
then
functionality. 不过,至少有一个库使用期限一般为抽象的同步和错误处理,而不是提供then
功能。 10 It's unclear if avoiding the term 'promise' was intentional, but probably a good choice since promises are built around 'thenables.' 10目前尚不清楚是否有意避免使用“承诺”一词,但这可能是一个不错的选择,因为承诺是围绕“ thenables”建立的。 2 2
References 参考
- Wikipedia on Promises & Futures 关于承诺和未来的维基百科
- Promises/A+ spec 承诺/ A +规范
- DOM Standard on Promises DOM承诺标准
- DOM Standard Promises Spec WIP DOM标准承诺规范WIP
- DOJO Toolkit Deferreds DOJO工具箱延迟
- jQuery Deferreds jQuery Deferreds
- Q Q
- FutureJS FutureJS
- Functional Javascript section on Promises 关于承诺的功能性Javascript部分
- Futures in AngularJS Integration Testing AngularJS集成测试中的期货
Misc potentially confusing things 杂物可能会混淆
Difference between Promises/A and Promises/A+ 承诺/ A和承诺/ A +之间的区别
(TL;DR, Promises/A+ mostly resolves ambiguities in Promises/A) (TL; DR,Promises / A +大部分解决了Promises / A中的歧义)
#4楼
- A
promise
represents a value that is not yet known 一个promise
代表一个未知的价值 - A
deferred
represents work that is not yet finisheddeferred
代表尚未完成的工作
A promise is a placeholder for a result which is initially unknown while a deferred represents the computation that results in the value. Promise是结果的占位符,该结果最初未知,而Deferred表示产生值的计算。
Reference 参考
- http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt1-theory-and-semantics http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt1-theory-and-semantics
#5楼
A Promise represents a proxy for a value not necessarily known when the promise is created. 一个Promise代表一个在创建Promise时不一定知道的值的代理。 It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. 它允许您将处理程序与异步操作的最终成功值或失败原因相关联。 This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future. 这样,异步方法就可以像同步方法一样返回值:异步方法将返回最终值,而不是最终值。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
The deferred.promise()
method allows an asynchronous function to prevent other code from interfering with the progress or status of its internal request. deferred.promise()
方法允许异步函数防止其他代码干扰其内部请求的进度或状态。 The Promise exposes only the Deferred methods needed to attach additional handlers or determine the state ( then, done, fail, always, pipe, progress, state and promise ), but not ones that change the state ( resolve, reject, notify, resolveWith, rejectWith, and notifyWith ). Promise仅公开附加其他处理程序或确定状态( 然后,完成,失败,总是,管道,进度,状态和 Promise)所需的Deferred方法,但不公开更改状态的方法( resolve,reject,notify,resolveWith, rejectWith和notifyWith )。
If target is provided, deferred.promise()
will attach the methods onto it and then return this object rather than create a new one. 如果提供了target,则deferred.promise()
会将方法附加到其上,然后返回此对象,而不是创建一个新对象。 This can be useful to attach the Promise behavior to an object that already exists. 这对于将Promise行为附加到已存在的对象很有用。
If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. 如果要创建延迟,请保留对延迟的引用,以便在某个时候可以解决或拒绝该延迟。 Return only the Promise object via deferred.promise() so other code can register callbacks or inspect the current state. 通过deferred.promise()仅返回Promise对象,以便其他代码可以注册回调或检查当前状态。
Simply we can say that a Promise represents a value that is not yet known where as a Deferred represents work that is not yet finished. 可以简单地说, Promise表示一个未知的值,而Deferred表示尚未完成的工作。
#6楼
In light of apparent dislike for how I've attempted to answer the OP's question. 考虑到我对尝试回答OP的问题的明显不满。 The literal answer is, a promise is something shared w/ other objects, while a deferred should be kept private. 字面上的答案是,诺言是与其他对象共享的东西,而延期应保持私有。 Primarily, a deferred (which generally extends Promise) can resolve itself, while a promise might not be able to do so. 首先,延期(通常扩展为Promise)可以解决自己,而Promise可能无法解决。
If you're interested in the minutiae, then examine Promises/A+ . 如果您对细节有兴趣,请检查Promises / A + 。
So far as I'm aware, the overarching purpose is to improve clarity and loosen coupling through a standardized interface. 据我所知,总体目的是提高清晰度并通过标准化接口放松耦合。 See suggested reading from @jfriend00: 请参阅@ jfriend00的建议阅读内容:
Rather than directly passing callbacks to functions, something which can lead to tightly coupled interfaces, using promises allows one to separate concerns for code that is synchronous or asynchronous. 使用promise而不是直接将回调传递给函数(可以导致接口紧密耦合),而是使用promise可以分离对同步或异步代码的关注。
Personally, I've found deferred especially useful when dealing with eg templates that are populated by asynchronous requests, loading scripts that have networks of dependencies, and providing user feedback to form data in a non-blocking manner. 就个人而言,我发现在处理例如由异步请求填充的模板,加载具有依赖性网络的脚本以及以非阻塞方式提供用户反馈以形成数据时,推迟特别有用。
Indeed, compare the pure callback form of doing something after loading CodeMirror in JS mode asynchronously (apologies, I've not used jQuery in a while ): 确实,比较以异步方式在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.");
};
});
To the promises formulated version (again, apologies, I'm not up to date on jQuery): 对于promise制定的版本(再次,抱歉,我在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.");
});
});
Apologies for the semi-pseudo code, but I hope it makes the core idea somewhat clear. 对半伪代码表示歉意,但我希望它可以使核心思想更加清晰。 Basically, by returning a standardized promise, you can pass the promise around, thus allowing for more clear grouping. 基本上,通过返回标准化的承诺,您可以传递承诺,从而可以进行更清晰的分组。