Tow*_*wer 297 javascript future promise deferred
延期,承诺和期货有什么区别?
这三者背后是否有普遍认可的理论?
Woa*_*dae 144
这些答案,包括所选择的答案,是良好的概念引入的承诺,但在细节缺乏究竟差别在使用图书馆实现它们(还有时出现的术语 是重要的区别).
由于它仍然是一个不断发展的规范,目前的答案来自于试图调查两个引用(如维基百科)和实现(如jQuery):
推迟:从不在流行参考文献中所述,
1 2 3 4
作为承诺分辨率(实施仲裁器,但常用的实现方式和).
5 6 7
resolvereject
有时deferreds也承诺(实现then),
5个6
其他时候它看作是更纯粹的有递延只能分辨率,并迫使用户访问的承诺使用.
7
then
承诺:正在讨论的战略中最全面的词.
一个代理对象,存储我们想要抽象的同步性的目标函数的结果,以及then接受另一个目标函数并返回一个新的promise的函数.
2
CommonJS的示例:
> asyncComputeTheAnswerToEverything()
.then(addTwo)
.then(printResult);
44
Run Code Online (Sandbox Code Playgroud)
未来:在一些热门的参考文献中一个看似过时期限 1 和至少一个流行的实现, 8 但看似偏爱"承诺"一词被淘汰的讨论 3 ,不要总是在介绍流行的话题提及. 9
但是,至少有一个库通常使用该术语来抽象同步性和错误处理,而不提供then功能.
10
目前还不清楚是否有意避免使用"承诺"一词,但可能是一个很好的选择,因为承诺是围绕'可能的'建立的.
2
(TL; DR,Promises/A +主要解决Promises/A中的歧义)
fnc*_*omp 97
显然不喜欢我试图回答OP的问题.字面上的答案是,承诺是与其他对象共享的东西,而延迟应该保密.主要是,延迟(通常扩展为Promise)可以自行解决,而承诺可能无法解决.
如果你对细节感兴趣,那么检查Promises/A +.
据我所知,最重要的目的是通过标准化界面提高清晰度并放松耦合.查看来自@ jfriend00的建议阅读:
不是直接将回调传递给函数,而是使用promises可以导致紧密耦合的接口,而是可以分离对同步或异步代码的关注.
就个人而言,我发现deferred在处理例如由异步请求填充的模板,加载具有依赖关系网络的脚本以及提供用户反馈以非阻塞方式形成数据时特别有用.
事实上,比较做一些纯回调形式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.");
};
});
Run Code Online (Sandbox Code Playgroud)
对承诺制定的版本(再次,道歉,我不是最新的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.");
});
});
Run Code Online (Sandbox Code Playgroud)
为半伪代码道歉,但我希望它使核心思想有些清晰.基本上,通过返回标准化的承诺,您可以传递承诺,从而允许更清晰的分组.
Cam*_*tin 72
Domenic Denicola的这次演讲让我真正点击了这一切.
在github的要点中,他给出了我最喜欢的描述,它非常简洁:
承诺的重点是让我们回到异步世界中的功能组合和错误冒泡.
换句话说,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);
}
);
Run Code Online (Sandbox Code Playgroud)
它就像你在编写这个同步代码一样:
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);
}
Run Code Online (Sandbox Code Playgroud)
(如果这仍然听起来很复杂,请观看该演示!)
关于延期,这是一种方式.resolve()或.reject()承诺.在Promises/B规范中,它被称为.defer().在jQuery中,它是$.Deferred().
请注意,据我所知,jQuery中的Promise实现已经破坏(参见gist),至少从jQuery 1.8.2开始.
它应该实现Promises/A thenables,但是你没有得到正确的错误处理,因为整个"异步try/catch"功能都不起作用.遗憾的是,因为拥有异步代码的"try/catch"非常酷.
如果你要使用的承诺(你应该尝试他们用自己的代码!),用克里斯科瓦尔Q值.jQuery版本只是一些用于编写更清晰的jQuery代码的回调聚合器,但是忽略了这一点.
关于Future,我不知道,我在任何API中都没有看到过.
编辑: Domenic Denicola对承诺YouTube的谈话从@Farm下面的评论.
迈克尔·杰克逊(是的,迈克尔·杰克逊)在视频中引述:
我希望你在脑海中刻录这句话: 承诺是一种异步价值.
这是一个很好的描述:承诺就像是来自未来的变量 - 对某些东西的一流参考,在某种程度上,它将存在(或发生).
IRS*_*HAD 29
一个承诺代表某个值的代理创建承诺时未必知道.它允许您将处理程序与异步操作的最终成功值或失败原因相关联.这允许异步方法返回类似于同步方法的值:异步方法返回一个在将来的某个时刻具有值的承诺,而不是最终值.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
该deferred.promise()方法允许异步函数防止其他代码干扰其内部请求的进度或状态.Promise只公开附加其他处理程序或确定状态(然后,完成,失败,总是,管道,进度,状态和承诺)所需的延迟方法,而不是那些改变状态的方法(resolve,reject,notify,resolveWith, rejectWith,和notifyWith).
如果提供了target,deferred.promise()则将方法附加到其上,然后返回此对象而不是创建新对象.这可以用于将Promise行为附加到已存在的对象.
如果要创建Deferred,请保留对Deferred的引用,以便在某些时候可以解析或拒绝它.通过deferred.promise()仅返回Promise对象,以便其他代码可以注册回调或检查当前状态.
简单地说,我们可以说Promise表示一个尚未知道的值,其中Deferred表示尚未完成的工作.