何时使用jQuery动画承诺而不是回调?

时间:2016-02-01 21:51:54

标签: javascript jquery promise

我有以下查询。 何时使用:

$('#box').hide(2000).promise().done(function(){
     $('#output').text('Box is hidden');
});

而不是:

$('#box').hide(2000,function(){
     $('#output').text('Box is hidden');
});

使用jQuery动画的.promise()方法有哪些有用的方案?

谢谢

1 个答案:

答案 0 :(得分:12)

如果你只是为一个项目设置动画,那么没有理由在直接回调中使用承诺。在这种特殊情况下,当您尝试协调多个不同的异步操作(承诺通常最有用的地方)时,promises会更有用。

假设你有一大堆你隐藏的物品,当你完成所有这些时你想要一个回调。然后,这将完全是这样:

$('.items, .boxes').hide(2000).promise().then(function(){
     $('#output').text('All hidden');
});

或者,假设您想知道何时完成了多个不同的动画,因此您需要协调多个动作。 Promise具有内置功能,这些功能可以在没有承诺的情况下进行手动编码:

var p1 = $('.items, .boxes').hide(2000).promise();
var p2 = $('.sliders').slideUp(2500).promise();
var p3 = $('.openers').slideDown(1500).promise();
$.when(p1, p2, p3).then(function() {
    // all are done here
});

如果你想在没有承诺的情况下处理代码,那么你将需要维护一个计数器,并在每个单独的回调中检查计数器以查看它们是否全部完成。这是更多的代码。现在,如果你有处理错误或链接到其上的多个其他操作,任何没有回调或没有一些异步支持库的选项很快就会成为手动代码的真正痛苦。这就是发明承诺的原因。

或者,甚至超出动画范围,想象你想要协调一个动画和一个ajax调用(你不知道需要多长时间):

var p1 = $('.items, .boxes').hide(2000).promise();
var p2 = $.ajax(...);
$.when(p1, p2).then(function() {
    // both are done here
});

以下是通知差异的演示。如果您按“重置”,然后按“回拨”,您将看到您收到5个完成通知。如果您按“重置”然后按“承诺”,您将看到完成后会收到1个完成通知。

// configure logging
log.id = "results";

$("#runPromises").click(function() {
  $('.items, .boxes').hide(2000).promise().then(function(){
       log("got done notification")
  });
});
$("#runCallbacks").click(function() {
  $('.items, .boxes').hide(2000, function(){
       log("got done notification")
  });
});

$("#reset").click(function() {
  $(".items, .boxes").show();
  $("#results").empty();
});
.items {
  height: 50px;
  width: 200px;
  background-color: red;
  margin-top: 10px;
}

.boxes {
  height: 30px;
  width: 30px;
  background-color: blue;
  margin-top: 10px;
}
#results {
  margin-top: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://files.the-friend-family.com/log.js"></script>
<button id="runCallbacks">Callbacks</button> 
<button id="runPromises">Promises</button>
<button id="reset">Reset</button>
<div>
  <div class="items"></div>
  <div class="items"></div>
  <div class="items"></div>
  <div class="boxes"></div>
  <div class="boxes"></div>
</div>
<div id="results"></div>