通过 jQuery addClass 调用使用标准 JS 承诺

Posted

技术标签:

【中文标题】通过 jQuery addClass 调用使用标准 JS 承诺【英文标题】:Use standard JS promises with jQuery addClass call 【发布时间】:2017-05-13 01:31:21 【问题描述】:

我试图让浏览器中的一系列事件一个接一个地发生,但是 javascript 是异步的,这使得这变得困难。我正在使用 jQuery 来处理添加和删除类,并且我想使用标准的 JS 承诺来使所有事情都按顺序发生,但我遇到了困难。我想要做的是将 jQuery 事件包装在 Promise.resolve() 中并使用它来调用 .then() (我过去通过 AJAX 调用成功地做到了这一点。)例如:

    makePromise = function() 
      return Promise.resolve($(".mydiv").addClass("grow").promise());
     
    makePromise().then(function() 
      alert("running");
    )
    .mydiv 
      height: 100px;
      width: 100px;
      background-color: blue;
    

    .mydiv.grow 
	    transition: width 2s;
        width: 500px;
    
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mydiv">
    </div>

JS Fiddle Here

目的是让 jQuery 事件按正常运行,然后运行 ​​then() 调用中正在发生的事情,但正如您所见,它无需等待就直接进入下一步。有没有办法让这部戏发挥作用,还是我完全走错了方向?帮助我 Stack Overflow Hivemind,你是我唯一的希望。

【问题讨论】:

addClass 是同步的,你为什么要把它包装在一个承诺中? 只需删除Promise.resolve,保留如下:return $(".mydiv").addClass("grow").promise();。如果您希望动画在显示警报之前结束,您可能需要阅读this。 如果你想等待 CSS 转换,你需要明确地等待那个事件。 addClass 是简单的同步 DOM 修改。 【参考方案1】:

JavaScript 默认为synchronous。因此,如果它们不是 async 之类的调用,您可以一个接一个地进行任何窗口事件

setTimeout

AJAX

Promise(不直接)

因此您的事件可以在不使用Promise 的情况下进行排序。

$(".mydiv").addClass("grow");

setTimeout(function() 
  alert("running");
  , 2000);
.mydiv 
      height: 100px;
      width: 100px;
      background-color: blue;
      transition: width 2s;
    

    .mydiv.grow 
      width: 500px;
    
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mydiv">
    </div>

甚至Promise 也用于使JavaScript 异步。

举个例子

var promise = new Promise(function(resolve, reject)
  console.log("First"); //Executes first.
  resolve();
);

promise.then(function() //purely async, called and not waited for response
  console.log("Third"); //after execution of promise.
);

console.log("second"); //not waited for promise.then

然后达到您对使用Promise 进行顺序执行的期望。我们需要一些asynchronism 来要求resolve 等待某个时间,所以使用基本的setTimeout 来实现这一点。

makePromise = function() 
      return new Promise(function(resolve, reject)
         $(".mydiv").addClass("grow").promise()
         setTimeout(resolve, 1000);
      )
     
    makePromise().then(function() 
      alert("running");
    )
.mydiv 
      height: 100px;
      width: 100px;
      background-color: blue;
      transition: width 3s;
    

    .mydiv.grow 
      width: 500px;
    
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mydiv">
    </div>

注意:我认为您的transitionwidth 存在问题。更正它以获得更好的结果。

希望这会有所帮助。

【讨论】:

以上是关于通过 jQuery addClass 调用使用标准 JS 承诺的主要内容,如果未能解决你的问题,请参考以下文章

解决jQuery(e).addclass(‘xxx‘)始终不生效的问题 - $(...).addclass is not a function

关于通过addClass与removeClass用jquery控制有良好兼容的CSS3样式

Javasript设计模式之链式调用

使用 jQuery UI 或 CSS 动画 addClass 和 removeClass [重复]

jQuery 链式写法

jQuery addClass removeClass toggleClass方法概述