jquery .done()中的异步回调函数未执行

时间:2018-01-12 13:23:01

标签: javascript jquery asynchronous async-await

为什么给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显示出所需的效果。您可以尝试交换注释掉的行,看看没有任何反应。注释掉的行是您通常期望功能的工作方式

3 个答案:

答案 0 :(得分:2)

问题是在jQuery 3之前,$.Deferred(jQuery promise api)不符合Promises A+

为了传递对async函数的引用,请使用then()(更标准的promise方法)而不是done()并使用jQuery v3 +

title.fadeTo(1000, 1).promise().then(reveal)

Working fiddle

答案 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',因此失败。