简体   繁体   中英

How to use $.when for a callback function?

I want to say when this function close() is finished run this function init(). But it's not working for me.

$.when(close(toolTip)).done(init(toolTip, anchor));

I am not using the $.when for anything ajax related, just trying to make sure close() is finished before I call init(), and no I can't stick init() at the end of close(). Any ideas?

ok here is close()

var close = function (toolTip) {
    toolTip.fadeOut('fast', function (e) {
        if (typeof e !== 'undefined') {
            //Re-set values applied when initted
            var toolTipBd = toolTip.find('.bd:first');
            toolTip.css('width', '');
            toolTipBd.css('max-height', '');
            toolTip.css('max-height', '');
            toolTipBd.css('overflowY', '');
        }
    });
};

No where in close() can it call init().

Your close() implementation should be like this:

var close = function (toolTip) {
    var d = $.Deferred();

    toolTip.fadeOut('fast', function (e) {
        if (typeof e !== 'undefined') {
            //Re-set values applied when initted
            var toolTipBd = toolTip.find('.bd:first');
            toolTip.css('width', '');
            toolTipBd.css('max-height', '');
            toolTip.css('max-height', '');
            toolTipBd.css('overflowY', '');
        }

        d.resolve();
    });

    return d.promise();
};

$.when works with Deferred 's . It returns a new Deferred which will resolve when all the Deferred 's you provided resolve.

As close() doesn't seem to be returning a Promise, when will resolve straight away (per the docs for when() .

However, if close() is synchronous, you don't need when() at all. If it is asynchronous, you need to return a Promise , and resolve it when your animation or whatever has completed;

function close(what) {
    var promise = jQuery.Deferred();

    what.fadeOut('slow', function () {
        promise.resolve();
    });

    return promise.promise();
}

... but you still don't need $.when as only 1 promise is involved. $.when is only useful when multiple promises are at play.

close(toolTip).done(function () {
    init(toolTip, anchor);
});

Note also that done(init(tooltip, anchor)) will call init immediately, and pass the result of that function invocation to done() ; instead, you need to pass a function to done. As init needs parameters, we've fixed this by introducing an anonymous function. If init didn't need any parameters, it'd have been as simple as:

close(toolTip).done(init);

Simply return toolTip:

return toolTip.fadeOut(...

using the callback to resolve a deferred object can result in odd results if there are more than one elements selected for whatever reason.

This works because jQuery objects have a .promise method that when called, return a promise object that resolves when all active animations are completed. $.when calls .promise on all passed in arguments.

You'll also need to call init differently, for example,

$.when(close(toolTip)).done(function(){
    init(toolTip, anchor);
});

And, as pointed out by others, you could then shorten that to

close(toolTip).promise().done(function(){
    init(toolTip, anchor);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM