4

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

<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.log($("div").each(function (i) {}));

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

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

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

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

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

4

2 回答 2

4

我从未见过each与承诺一起使用,但只有动画

$('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()手动延迟)

于 2013-01-19T14:48:38.657 回答
2

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

$("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()就会激活 。

于 2013-01-19T14:11:01.230 回答