3

I'm trying to get a series of events to occur in the browser one after the other, but JavaScript being asynchronous makes that difficult. I'm using jQuery to handle adding and removing classes, and I want to use standard JS promises to make everything occur in sequence but I'm having a hard time of things. What I'm trying to do is wrap the jQuery event in Promise.resolve() and use that to call .then() (I've had success with this in the past with AJAX calls.) For example:

    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

The intent is for the jQuery event to run it's course, then run what's going on in the then() call, but as you can see it's marching right on into the next step without waiting. Is there a way to make this play work or am I going in the wrong direction entirely? Help me Stack Overflow Hivemind, you're my only hope.

Jyothi Babu Araja
  • 10,076
  • 3
  • 31
  • 38
Jonathon Nordquist
  • 2,066
  • 4
  • 21
  • 23
  • 1
    `addClass` is synchronous, why are you trying to wrap it in a promise? – Alexander O'Mara Dec 28 '16 at 18:23
  • Just remove the `Promise.resolve`, leave it like this: `return $(".mydiv").addClass("grow").promise();`. If you want the animation to end before showing the alert you probably want to read [this](http://stackoverflow.com/questions/2087510/callback-on-css-transition). – Martin Mendez Dec 28 '16 at 19:14
  • If you want to wait for the CSS transition, you will need to explicitly wait for that event. `addClass` is simple synchronous DOM modification. – Bergi Dec 28 '16 at 19:37

1 Answers1

0

JavaScript is synchronous by default. So you can make whatever your window events one after other, if they are not async calls like

setTimeout

AJAX

Promise (not directly)

So your events can be sequenced without using 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>

And even Promise is used to make JavaScript asynchronous.

As an example

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

Then coming to your expectation of making sequential execution using Promise. We need some asynchronism to ask resolve to wait for sometime, so used basic setTimeout to achieve this.

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>

Note: I think some issue with your transition for width. correct it for better result.

Hope this helps.

Community
  • 1
  • 1
Jyothi Babu Araja
  • 10,076
  • 3
  • 31
  • 38