记住这句话:
一旦对象进入已解决或被拒绝状态,它就会保持该状态。回调仍然可以添加到已解决或被拒绝的延期 - 它们将立即执行。
来自http://api.jquery.com/jQuery.Deferred/ 的
您希望此代码产生什么:
var d = $.Deferred();
var a = function() {
d.done(function() {
console.log('inner');
});
console.log('outer');
};
d.done(a);
d.resolve();
我希望它是inner
,然后是outer
。虽然我检查的任何jquery版本都不是这样的。
你会认为这是一个错误,还是我错过了描述中的观点?
对应的JSFiddle:http://jsfiddle.net/U8AGc/
UPD :该问题的一些背景知识:我希望a
方法的行为类似,无论调整的方式如何:a()
或{{1 }}
答案 0 :(得分:3)
我希望a方法的行为类似,无论它是如何被调用的:只是a()或d.done(a)
没有。 d.done(a)
并不总是立即致电a()
- 最明显的是d
尚未解决。
Promises/A+通过要求处理程序始终以异步方式触发来解决这种歧义,即在每种情况下,outer
都可以inner
。
我希望它是
inner
,然后outer
由jQuery.Callbacks
阻止,firing
flag具有明确的{{3}},用于不在处理程序内立即执行处理程序;相反,添加的处理程序将附加到队列中。它也是防止堆栈溢出的一个功能,它通过"锁定"简化了fire
功能。它
你会认为这是一个错误,还是我错过了描述中的观点?
我考虑不遵循Promises / A +这个错误:-)描述只是没有处理这个 - 非常罕见 - 特殊情况。
我说它的观点是,即使在解决方案之后仍然会自动执行已解决的延迟的处理程序,立即执行"他们并不一定意味着.done
"同步而是#34;马上和#34;。
答案 1 :(得分:1)
这里发生了什么:
var a = function() {
// the function logging 'inner' is *added* to the call stack
d.done(function() {
console.log('inner');
});
// 'outer' is logged
console.log('outer');
};
// `a` has finished executing, then the anonymous function logs 'inner'
我已经在your JSFiddle中添加了一个包含堆栈跟踪*的日志 - 您可以看到函数a
在找不到的anon函数中找不到inner
{ {1}} - jQuery在a
完成排除后调用它。
jQuery源代码中的相关行是found here(注意它已添加到队列中)。
*来自here
的跟踪代码