根据http://api.jquery.com/jquery.when/ $.when()
,拒绝其中一个延期被拒绝的主延期。为什么我在获取OnPreRenderFailed'之前获得所有4个console.log消息。消息。
我的理解是,一旦第二次延期被拒绝,我就不应该console.log('third deferred');
和console.log('fourth deferred');
或在console.log('caught OnPreRenderFailed');
之后获得它们
除非我是超级幸运(或不是)让方法始终以(1,3,4,2)顺序发射。我必须在这里遗漏一些东西
JSFiddle
$(document).on('OnPreRenderResolved', function () {
console.log('caught OnPreRenderResolved');
});
$(document).on('OnPreRenderFailed', function () {
console.log('caught OnPreRenderFailed');
})
$(document).on('OnPreRender', function (e, options) {
console.log('OnPreRender fired');
options.callback();
});
$(document).trigger('OnPreRender', {
callback: function () {
$.when.apply($, [$.Deferred(function (deferred) {
console.log('first deferred');
deferred.resolve();
}), $.Deferred(function (deferred) {
console.log('second deferred');
deferred.reject();
}), $.Deferred(function (deferred) {
console.log('third deferred');
deferred.resolve();
}), $.Deferred(function (deferred) {
console.log('fourth deferred');
deferred.resolve();
})]).then(function () {
$(document).trigger("OnPreRenderResolved");
}, function () {
$(document).trigger("OnPreRenderFailed");
})
}
});
答案 0 :(得分:2)
问题是评估始终是同步的。你不能强迫两者之间的任何东西。所以为了做到这一点,你必须强制你的函数异步。您可以使用setTimeout(..., 0);
:
$.when.apply($, [
$.Deferred(function (deferred) {
setTimeout(function() {
console.log('first deferred');
deferred.resolve();
}, 0);
}),
$.Deferred(function (deferred) {
setTimeout(function() {
console.log('second deferred');
deferred.resolve();
}, 0);
}),
...
]);
不要将$.when
与同步代码一起使用。这简直毫无意义。
但请注意,未定义setTimeout的顺序。你可能会得到奇怪的结果。
答案 1 :(得分:1)
这种情况正在发生,因为JS解释器必须先评估传递给$.when
的参数才能真正调用$.when
。
由于对$.Deferred
的调用都是内联参数,因此它们都会完成(输出他们的console.log
消息),但只有在完成后才会$.when
继续进行,{指出它将确定其中一个承诺被拒绝。
就像你写的那样:
f(a(), b(), c(), d());
每个a
... d
必须在f
被调用之前返回。
此外,由于您的任何一个函数都没有启动任何异步操作,因此在调用$.when
之后,在调用之后出现的控制台输出绝对没有机会。
答案 2 :(得分:0)
不完全,什么时候仍然被拒绝但是其他异步进程没有停止,什么时候会在第一个无法解决时立即报告拒绝。我见过的唯一能够取消承诺的图书馆是蓝鸟