【问题标题】:When to use jQuery animation promises instead of the callback?何时使用 jQuery 动画承诺而不是回调?
【发布时间】:2017-03-09 00:16:47
【问题描述】:

我有以下问题。 何时使用:

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

而不是这个:

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

在 jQuery 动画中使用 .promise() 方法有哪些有用的场景?

谢谢

【问题讨论】:

  • 对于这种情况,没有。承诺很有用for more complicated cases
  • 我发现 Promises 最常用于返回 XHR 请求或任何其他异步事件的响应。
  • 请重新打开这个问题。伙计们,对此的答案根本不必主要基于意见。有很好的支持事实为什么一个比另一个更好。阅读提供的答案。这主要不是意见。尝试编写一个函数来协调四个不同的定时异步操作,而不使用 Promise。这是一吨更多的代码。任何知道如何使用 Promise 的人都会明白如何使用 Promise 进行更简单的设计。
  • @SamAxe - 问题的意思是为什么人们会在动画中使用承诺。答案是当您有多个要协调的事情时使用它们。这主要不是一种意见。它很容易用事实和例子来展示。这里的人太快了关闭一些,因为它可以有一个基于意见的答案,而完美的非基于意见的答案总是可能的。如果有人提供的答案不是主要意见,则不应关闭该问题。制定此规则是为了防止意见辩论。这里几乎没有危险。
  • 请记住,只有在常见问题解答和关闭投票描述中,问题才应该被投票关闭以获得意见:“对这个问题的回答几乎完全基于意见,而不是事实、参考资料或特定专业知识”。您不会仅仅因为可以通过意见回答问题而投票结束,只有当这真的是唯一可以回答的方式时。

标签: javascript jquery promise


【解决方案1】:

如果您只是为一个项目设置动画,则几乎没有理由使用 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>

【讨论】:

  • $.ajax() 会自动创建一个 promise,还是需要将最后一个示例调整为 var p2 = $.ajax(...).promise();
  • @SamAxe - $.ajax() 已经返回了一个承诺。您必须将 .promise() 与动画一起使用,因为所有动画函数的默认值是返回 jQuery 对象,因此您可以链接 jQuery 操作,例如 $("#box").slideUp().slideDown(), so if you want a promise, you have to ask for one with .promise( )` 用于动画。
  • 谢谢。了解这一点很有帮助。
  • 很好的答案!非常感谢。我无意挑起这场动荡。当然,我的查询不仅仅是关于动画;它通常与承诺及其使用有关......
  • @ILIAS - 如果您想了解更多关于何时使用一般承诺或哪些承诺最适合使用,甚至为什么要使用承诺的更多信息,您可以阅读数百篇关于该主题的非常好的文章用谷歌查找。关键的答案是协调多个异步操作和更容易更健壮的错误处理,尤其是在涉及多个异步操作时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 2015-03-25
  • 1970-01-01
  • 2014-04-27
相关资源
最近更新 更多