jQuery animate() 是一个承诺吗?

Posted

技术标签:

【中文标题】jQuery animate() 是一个承诺吗?【英文标题】:Is the jQuery animate() a promise? 【发布时间】:2019-12-25 18:03:32 【问题描述】:

我发现 jQuery animate() 的行为有点像 Promise,因为一个任务会先完成,然后再执行第二个任务,非常像两个链式 Promise。

在下面的代码中设置divhtml可以在动画完成之前发生,这也表明animate()就像一个承诺——它立即返回并且是非阻塞的。

但我发现,如果我只是在一个元素 (#shape2) 上使用两个不同的动画调用 animate() 两次,它们将一个接一个地运行,而不是同时具有向下滑动和舍入的动画角落同时发生。实际上,它只是普通的 jQuery 链接,而不是 Promise 链接。

那么animate() 是不是一个承诺?

(如果是promise,console.log($("#shape").animate().then)不应该打印出undefined以外的东西吗?)

作为旁注,它的一个可能实现似乎只是使用setTimeoutsetInterval,为第一个animate() 执行一系列小动画,也许有一个currentAnimationID 是设置为 1 或某个随机 ID 值,第二个 animate() 根本不会运行,直到第一个动画完成并将 currentAnimationID 设置为 2 以便第二个动画开始。

或者在内部,第一个和第二个动画被实现为链式承诺,它们只是自动链接在一起。如果是这种情况,这种自动链接不是通常的承诺行为,而可能正是通常的动画要求所需要的。

$("#shape").animate(
  top: 100
, 1000).animate(
  borderRadius: 30
, 1000);

$("#shape2").animate(
  top: 100
, 1000);

$("#shape2").animate(
  borderRadius: 30
, 1000);

$("#shape").html("hello");
$("#shape2").html("world");
#shape, #shape2 
  background-color: #00BFFF;
  width: 100px;
  height: 100px;
  top: 0px;
  left: 50px;
  position: relative;
  border-radius: 0;
  display: inline-block;
  text-align: center;
  line-height: 100px;
  vertical-align: middle;
  font-size:18px


#shape2 
  left: 150px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="shape"></div>
<div id="shape2"></div>

jsfiddle 版本在https://jsfiddle.net/pnkrhxs8/15 不知为何,jsfiddle 版本中两个方块同时向下滑动,但在 *** 版本中,右侧方块向下滑动比左侧慢一点。

【问题讨论】:

我无法观察到这一点:“但在 *** 版本上,右边的方块向下滑动比左边的慢一点” "(如果它是一个承诺,不应该 console.log($("#shape").animate.then) .." 它不一定是。它在内部管理类似 (jquery.defered) 对象的承诺。它使用类似队列的系统来链接动画。source jQuery.animate() 返回 jQuery,允许您编写 jQuery.animate().animate()(如问题所示)。 jQuery.promise() 返回一个 Promise 对象,允许您“观察绑定到集合的特定类型的所有操作(无论是否排队)都已完成” - 在 jQuery documentation 中阅读更多内容。 setInterval 是您正在寻找的函数,如果您想在设定的时间间隔内执行操作developer.mozilla.org/en-US/docs/Web/API/… 【参考方案1】:

不,这不是承诺。它在fx queue of the jQuery element 中安排了一个效果,可以以承诺链无法做到的方式进行操作。

但是,是的,结果与 Promise 链非常相似,您可以使用 .promise() method 获得动画队列结束的 Promise,然后启动真正的 Promise 链。

【讨论】:

【参考方案2】:

它绝对不是一个承诺,因为它是一个函数调用。 Promise 是一个具有 3 种不同状态的对象:未决、已解决、已拒绝。 Promise 包含访问这些状态的方法:then()、catch()。运营商 ”。”只是为了访问函数的返回值。这意味着一个函数可以返回一个 Promise,然后您可以使用 functionCall().then() 访问 Promise 对象的 then() 方法

// resolves after 1sec
const promise1 = new Promise(function (resolve, reject) 
    setTimeout(function () 
        resolve("resolve promise1");
    , 1000);
);
// the promise object pending
console.log(promise1)
// printed after promise is resolved
promise1.then(res => 
    // logging resolve value
    console.log(res)
    // resolved promise object
    console.log(promise1)
)
// prints resolved after 3 seconds because the promise already was resolved
// aka defered promise
setTimeout(()=>
    promise1.then(res => console.log(res))
,3000)

【讨论】:

以上是关于jQuery animate() 是一个承诺吗?的主要内容,如果未能解决你的问题,请参考以下文章

属性的顺序与 jQuery 动画有关吗?

如何扩展 jQuery 的 animate-step 功能

jquery animate 怎么延迟执行

jQuery animate() 不使用颜色

在悬停时使用 jQuery .animate 显示新的 div

Jquery复习animate()一些值得注意的点