【问题标题】:Unsure of how to implement $.defered不确定如何实现 $.deferred
【发布时间】:2014-11-21 08:00:17
【问题描述】:

这应该很简单:我有一个 5 秒的动画,之后我想要 .append('Done')。我想利用延期。我使函数延迟,添加了一个解析语句(没有参数,所以我不确定是否需要),并让它返回一个承诺。但我无法让 .append 等待我的推子()执行。

$(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!');
  });

});

到目前为止,我尝试过的任何方法都不适合我。我做错了什么?

【问题讨论】:

    标签: jquery promise deferred


    【解决方案1】:

    你可以简单地从你的动画链的右手端获得一个承诺,并相应地回复.done()

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

    编辑

    好的,就目前而言,您在问题中的 Deferred 在第一个动画开始后立即解决。如果你想直接做,只是为了学习,那么你只需要在 fadeOut().fadeIn() 动画完成后解决你的 Deferred 。

    例如:

    $(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!');
        });
    );
    

    但这有点疯狂,因为当.fadeOut(2500).fadeIn(2500).promise() 已经生成一个已解决的承诺时,创建和解决您自己的延迟是不必要的,可以从fader 返回,从而避免所谓的“延迟反模式”:

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

    这在功能上与我上面原始答案中的解决方案相同,但 jQuery 方法链分为两部分:

    • 第一部分,$('...').fadeOut(...).fadeIn(...).promise(),在函数内部,
    • 第二部分,.done(function() {...}),链接到函数调用。

    这是可能的,因为 jQuery 方法链(涉及或不涉及 Promise)总是可以沿其长度的任意位置拆分,每个部分的结果要么从函数返回,要么分配。

    这里又是赋值:

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

    或者使用赋值执行的延迟反模式

    var dfr = new $.Deferred();
    $('#container').fadeOut(2500).fadeIn(2500).promise().done(dfr.resolve);
    
    var promise = dfr.promise();
    
    promise.done(function() {
        $('body').append('Done!');
    });
    

    但请理解,我并不是在提倡反模式。

    【讨论】:

    • 这回答了 OP 的问题,但在这种特殊情况下,使用 Promise 比仅使用来自 fadeIn(2500, fn) 的完成函数更多代码。当您等待完成一堆并行操作时,带有动画的 Promise 特别有用,但是在这个简单的场景中只有一个动画,它们只是更多的代码和更多的函数调用。
    • 这是一个选择问题。我倾向于这样做,因为它是标准的承诺处理,而不是一些特殊情况。
    • jQuery 动画上的补全函数并不是什么特殊情况——不知道你的意思。它们出现在工具包中的每个动画和 ajax 函数中。
    • 特殊情况可能不是最好的表达方式。也许“速记语法”会更好。
    • 来自 OP:是的,这在技术上是可行的,但我不关心简单案例的代码简洁性。我有目的地尝试学习如何使用 dfr/resolve/return。最终,我希望能够将延迟异步函数(比这更复杂的一个)定义为变量,然后调用执行以及在代码中进一步执行之后的内容(不是同时定义和执行) .让我困惑的是如何在这种情况下使用承诺。我很惊讶fader().done(fn) 不起作用,我不知道为什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2013-08-08
    • 1970-01-01
    相关资源
    最近更新 更多