如果您只是为一个项目设置动画,则几乎没有理由使用 Promise 而不是直接回调。在这种特殊情况下,当您尝试协调多个不同的异步操作时,Promise 会更有用(这通常是 Promise 最有用的地方)。
假设您有一大堆要隐藏的项目,并且您希望在它们全部完成后进行一次回调。那么,这正是这样做的:
$('.items, .boxes').hide(2000).promise().then(function(){
$('#output').text('All hidden');
});
或者,假设您想知道何时完成了多个不同的动画,因此您需要协调多个动作。 Promise 具有内置功能,无需 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
});
如果您想在没有承诺的情况下提交代码,那么您将必须维护一个计数器,并在每个单独的回调中检查计数器以查看它们是否都已完成。这是更多的代码。现在,如果您有错误需要处理或多个其他操作链接到此,任何没有回调或没有一些异步支持库的选项很快就会成为手工代码的真正痛苦。这就是为什么要发明 Promise 的原因。
或者,甚至超越动画,想象一下您想要协调动画和 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>