admin管理员组

文章数量:1405393

Why does giving an async function as a callback function for a jQuery deferred.done() not work? i.e. Why does

jqueryObj.fadeTo("slow", 1)
    .promise().done(asyncFunc);

not work, but

jqueryObj.fadeTo("slow", 1)
    .promise().done(function() {
        asyncFunc();
    );

does?

(Also, note that jqueryObj.click(asyncFunc) does work.)


Example:

<h2>Title</h2>
<ul>
  <li>Item</li>
  <li>Item</li>
  ...
</ul>

After the title has finished faded in, each item of the list fades in, in order. The fade time is 20000 ms, but the delay between list items is 250 ms (so the next list item starts fading in while the previous is still ongoing).

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 showing the desired effect. You can try swapping for the mented out line to see nothing happens. The mented out line is how you normally expect functions to work

Why does giving an async function as a callback function for a jQuery deferred.done() not work? i.e. Why does

jqueryObj.fadeTo("slow", 1)
    .promise().done(asyncFunc);

not work, but

jqueryObj.fadeTo("slow", 1)
    .promise().done(function() {
        asyncFunc();
    );

does?

(Also, note that jqueryObj.click(asyncFunc) does work.)


Example:

<h2>Title</h2>
<ul>
  <li>Item</li>
  <li>Item</li>
  ...
</ul>

After the title has finished faded in, each item of the list fades in, in order. The fade time is 20000 ms, but the delay between list items is 250 ms (so the next list item starts fading in while the previous is still ongoing).

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 showing the desired effect. You can try swapping for the mented out line to see nothing happens. The mented out line is how you normally expect functions to work

Share Improve this question edited Mar 15, 2018 at 14:10 binaryfunt asked Jan 12, 2018 at 13:23 binaryfuntbinaryfunt 7,1475 gold badges44 silver badges65 bronze badges 2
  • In a ment on my deleted answer, you said you don't want to wait for the fadeTo to plete, you just want a 250ms delay between them. Your fiddle above does that (on a browser that supports async/await). – T.J. Crowder Commented Jan 12, 2018 at 13:34
  • I've edited the question to try and improve the clarity. The Question is at the beginning. – binaryfunt Commented Jan 12, 2018 at 13:37
Add a ment  | 

3 Answers 3

Reset to default 3

The problem is that prior to jQuery 3 , $.Deferred (jQuery promise api) was not Promises A+ pliant.

In order to pass a reference to an async function use then()(more standard promise method) instead of done() and use jQuery v3+

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

Working fiddle

This is because jQuery prior to version 3 simply doesn't support async delegates

Your first code is equivalent of:

jqueryObj.fadeTo("slow", 1)
    .promise().done(async() => await asyncFunc());

and not the code you provided.

This code doesn't work as well and this is because when you check the jQuery sources - it checks for ($.type === 'function') when you are registering a delegate.

For async function the .type returned is 'object' and not a 'function' and therefore it fails.

I am not totally sure that this is the reason, however, this is weird enough to be strongly suspect:

try this code:

$.isFunction(reveal); //returns false instead of true

本文标签: javascriptAsync callback function in jquery done() not executingStack Overflow