为什么给jQuery deferred.done()
的回调函数提供异步函数不起作用?即为什么
jqueryObj.fadeTo("slow", 1)
.promise().done(asyncFunc);
不起作用,但是
jqueryObj.fadeTo("slow", 1)
.promise().done(function() {
asyncFunc();
);
确实
(另请注意,jqueryObj.click(asyncFunc)
无效。)
示例:
<h2>Title</h2>
<ul>
<li>Item</li>
<li>Item</li>
...
</ul>
标题完成后,列表中的每个项目按顺序淡入。淡入淡出时间为20000毫秒,但列表项之间的延迟为250毫秒(因此下一个列表项开始淡入,而前一个列表项仍在进行中)。
JS:
var title = $("h2"),
listItems = $("ul li");
function wait(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
async function reveal() {
for (var i = 0; i < listItems.length; i++) {
$(listItems[i]).fadeTo(2000, 1);
await wait(250);
}
}
title.fadeTo(500, 1)
//.promise().done(reveal) doesn't work!
.promise().done(function() {
reveal();
});
Here is a JSFiddle显示出所需的效果。您可以尝试交换注释掉的行,看看没有任何反应。注释掉的行是您通常期望功能的工作方式
答案 0 :(得分:2)
问题是在jQuery 3之前,$.Deferred(jQuery promise api)不符合Promises A+。
为了传递对async
函数的引用,请使用then()
(更标准的promise方法)而不是done()
并使用jQuery v3 +
title.fadeTo(1000, 1).promise().then(reveal)
答案 1 :(得分:1)
我不完全确定这是原因,然而,这很奇怪,可以强烈怀疑:
试试这段代码:
$.isFunction(reveal); //returns false instead of true
答案 2 :(得分:1)
这是因为版本3之前的jQuery根本不支持异步委托
您的第一个代码相当于:
jqueryObj.fadeTo("slow", 1)
.promise().done(async() => await asyncFunc());
而不是您提供的代码。
此代码不起作用,这是因为当您检查jQuery源时 - 它会检查
注册代表时($.type === 'function')
。
对于异步函数,返回的.type是'object'而不是'function',因此失败。