Home Async callback function in jquery .done() not executing
Reply: 3

Async callback function in jquery .done() not executing

binaryfunt
1#
binaryfunt Published in 2018-01-12 13:23:01Z

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 something jqueryObj.click(asyncFunc) does work.)

Example: 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).

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

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 commented out line to see nothing happens. The commented out line is how you normally expect functions to work

charlietfl
2#
charlietfl Reply to 2018-01-12 14:32:39Z

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

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

Kaddath
3#
Kaddath Reply to 2018-01-12 14:01:08Z

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
Adassko
4#
Adassko Reply to 2018-01-12 14:06:32Z

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.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.310533 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO