Unsure of how to implement $.defered

可紊 提交于 2019-12-13 06:01:54

问题


This should be simple: I have a 5-second animation, after which I want to .append('Done'). I want to make use of deferrals. I made the function deferred, added a resolve statement (with no argument, so I'm not sure that's needed), and have it returning a promise. But I cannot get the .append to wait for my fader() to execute.

$(document).ready(function () {

  var fader = function () {
   var dfr = new $.Deferred();
    $('#container').fadeOut(2500).fadeIn(2500);
     dfr.resolve();
     return dfr.promise();
  };

/*   fader();

     $('#container').done(function(){   
       $('body').append('Done!');
     });
*/

  fader().done(function(){  
    $('body').append('Done!');
  });

});

Nothing I've tried so far is working for me. What am I doing wrong?


回答1:


You can simply obtain a promise from the right-hand end of your animation chain, and respond accordingly with .done().

$(document).ready(function () {
    $('#container').fadeOut(2500).fadeIn(2500).promise().done(function() {
        $('body').append('Done!');
    });
});

EDIT

OK, as it stands, your Deferred in the question is resolved immediately after the first animation starts. If you want to do it longhand, just for learning, then you need to resolve your Deferred only when the fadeOut().fadeIn() animations have completed.

For example :

$(document).ready(function () {
    function fader() {
        var dfr = new $.Deferred();
        $('#container').fadeOut(2500).fadeIn(2500).promise().done(function() {
            dfr.resolve();
        });
        //or more concisely
        // $('#container').fadeOut(2500).fadeIn(2500).promise().done(dfr.resolve);
        return dfr.promise();
    };
    fader().done(function() {
        $('body').append('Done!');
    });
);

But this is a bit crazy because creating and resolving your own Deferred is unnecessary when .fadeOut(2500).fadeIn(2500).promise() already generates a resolved promise, which can be returned from fader thus avoiding the socalled "Deferred anti-pattern" :

$(document).ready(function () {
    function fader() {
        return $('#container').fadeOut(2500).fadeIn(2500).promise();
    };
    fader().done(function() {
        $('body').append('Done!');
    });
);

This is functionally identical to the solution in my original answer above, but with the jQuery method chain split into two parts :

  • the first part, $('...').fadeOut(...).fadeIn(...).promise(), inside a function,
  • the second part, .done(function() {...}), chained to the function call.

This is possible because a jQuery method chain (involving or not involving promise) can always be split anywhere along its length, with the result of each part either returned from a function or assigned.

Here it is again with assignment :

var promise = $('#container').fadeOut(2500).fadeIn(2500).promise();

promise.done(function() {
    $('body').append('Done!');
});

Or the Deferred antipattern executed with assignment

var dfr = new $.Deferred();
$('#container').fadeOut(2500).fadeIn(2500).promise().done(dfr.resolve);

var promise = dfr.promise();

promise.done(function() {
    $('body').append('Done!');
});

But please understand, I'm not advocating the anti-pattern.



来源:https://stackoverflow.com/questions/24234792/unsure-of-how-to-implement-defered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!