嵌套的promise处理程序

时间:2014-03-26 01:03:53

标签: javascript jquery promise

记住这句话:

  

一旦对象进入已解决或被拒绝状态,它就会保持该状态。回调仍然可以添加到已解决或被拒绝的延期 - 它们将立即执行。

     来自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 }}

2 个答案:

答案 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

的跟踪代码