【问题标题】:Deferreds on jQuery.each result推迟 jQuery.each 结果
【发布时间】:2013-01-19 14:05:55
【问题描述】:

我正在学习延期,但无法弄清楚它是如何/为什么起作用的:

<html>
<head>
</head>
<body>
    <div>
        1</div>
    <div>
        2</div>
    <div>
        3</div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script>
        $("div").each(function (i) {
            $(this).delay(1000 * i).fadeOut();
        }).promise().done(function () { console.log("it's done"); });
</script>
</body>
</html>

特别是:为什么我可以在每个之后调用 promise?为什么它在技术上是可行的?我已经 console.logged:

console.log($("div").each(function (i) {}));

我确实在原型中看到了 promise 方法。但是,我的每个函数都没有返回任何值,只有一个:

$(this).delay(1000 * i).fadeOut();

那么,promise 是如何与动画结果相关联的呢? (基本上是每次迭代的结果)

编辑 1:为了清楚起见,也许我应该这样写我的问题:

done 方法是如何在所有动画完成后调用的 == promise 如何与每个回调函数内部执行的动画互连。

【问题讨论】:

    标签: javascript jquery jquery-deferred


    【解决方案1】:

    我从未见过each 与 promises 一起使用,而只是动画

    $('div') 
    .animate({opacity: 0}, 1500) // animate all divs at once
    .promise()
    .done(function(){ 
       console.log('all done');
    });
    

    这将立即为所有 div 设置动画,然后在所有 div 完成动画时执行回调。 循环内动画的问题是它无法协调,如果你不使用承诺,你将无法控制它们何时完成。如果你真的想使用each,你必须创建一个promises的数组,然后使用then

     var promises = [];
     $('div').each(function(){
        var $this = $(this);
        promises.push($this.fadeOut('slow').promise());
     });
    
     $.when.apply($, promises).then(function(){
       console.log('all done');
     });
    

    这与执行$('div').fadeOut('slow', function(){ alert('done'); }); 不同,因为回调将发生在每个动画元素上,而 Promise 处理就像它是一个包含许多子任务的“任务”

    http://jsfiddle.net/LbHrQ/3/

    promise 的最佳用途是当你想同步一些本质上的异步操作时,比如动画、ajax、使用超时的东西(在这种情况下,你需要手动 resolve() 你的 Deferred)

    【讨论】:

      【解决方案2】:

      您是否尝试在块中添加promise() 方法inside?目前,您只是在所有迭代完成后才执行它。

      $("div").each(function (i) {
         $(this).delay(1000 * i).fadeOut().promise().done(function () { console.log("This individual animation is done."); });
      }).promise().done(function () { console.log("Everything is done."); });
      

      您的选择器div 实际上是指您页面上的很多元素。当它遍历所有这些元素时,它会对该元素执行特定的操作。

      然后你要做的是要求 jQuery 在与这些元素相关的所有先前操作都完成后执行另一个操作。根据他们的文档,它返回一个对象:

      当某种类型的所有动作都绑定到集合、排队或 没有,已经结束了。

      因此,在集合中执行每个 fadeOut() 之后,console.log() 被激活。

      【讨论】:

      • 嗯,这就是我正在测试的 - 在所有迭代完成后执行它。而且我很好奇它是如何工作的 :) 我在一个教程中看到了它,它让我深思
      • 那么我的回答能满足你的需要吗?
      • 不。我很好奇在所有动画完成后调用 done 方法是如何完成的 == promise 如何与动画结果互连。
      • 我已经更新了我的答案。如果您有兴趣或想知道任何具体的事情,请提及,以便我提供帮助:)
      • 该方法返回一个动态生成的对象,根据 jQuery 文档,“一旦绑定到集合的特定类型的所有操作(无论是否排队)都结束,该对象就会被解析。”循环的每个成员都是集合的成员,因为它们具有相同的选择器。然后,jQuery 框架在内部跟踪每个元素上执行的每个事件/函数,并在每个成员完成时生成一个 Promise 对象。至于使 jQuery 工作的内部/核心 JavaScript,我不知道。
      猜你喜欢
      • 2017-10-29
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 2018-09-20
      • 2017-02-01
      • 2018-07-08
      • 1970-01-01
      • 2010-11-11
      相关资源
      最近更新 更多