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

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

在下面的代码中设置div的html可以在动画完成之前发生,这也表明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 版本中两个方块同时向下滑动,但在 Stackoverflow 版本中,右侧方块向下滑动比左侧慢一点。

【问题讨论】:

  • 我无法观察到这一点:“但在 Stackoverflow 版本上,右边的方块向下滑动比左边的慢一点”
  • "(如果它是一个承诺,不应该 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/…

标签: jquery promise jquery-animate


【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      相关资源
      最近更新 更多