1

I found the jQuery animate() behaves somewhat like a promise, because one task will finish first, before the second task is performed, very much like two chained promises.

The fact that setting the html of the div can happen before the animation completion in the code below, also suggests that animate() is like a promise -- it returns immediately and is non-blocking.

But I found that if I just call the animate() twice on an element (#shape2) with two different animations, they will run one after another, instead of having both animations of sliding-down and rounding-the-corner happen at the same time. In fact, it is just the usual jQuery chaining, not a promise chaining.

So is animate() a promise or not?

(if it is a promise, shouldn't console.log($("#shape").animate().then) print out something other than undefined?)

As a side note, it looks like one possible implementation of it is just using setTimeout or setInterval, to perform a series of small animations for the first animate(), and perhaps there is a currentAnimationID being set to 1 or some random ID value, the second animate() won't run at all, until the first animation finished and set the currentAnimationID to 2 so that the second animation will begin.

Or maybe internally, the first and second animations are implemented as chained promises and they are just automatically chained together. If that's the case, this automatic chaining is not a usual promise behavior but maybe just what is needed for usual animation requirements.

$("#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>

The jsfiddle version is on https://jsfiddle.net/pnkrhxs8/15 For some reason, in the jsfiddle version the two squares slide down at the same time, but on the Stackoverflow version, the right square slide down a little bit slower than the left one.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • I can not observe this : "but on the Stackoverflow version, the right square slide down a little bit slower than the left one" – Eldar Dec 25 '19 at 18:50
  • "(if it is a promise, shouldn't console.log($("#shape").animate.then) .." it doesn't have to be. It manages internally with promise like (jquery.deffered) objects. And it uses a queue like system to chain animations. [source](https://github.com/jquery/jquery/blob/c1ee33aded44051b8f1288b59d2efdc68d0413cc/src/effects.js#L501) – Eldar Dec 25 '19 at 19:00
  • `jQuery.animate()` returns jQuery, allowing you to write `jQuery.animate().animate()` (as in the question). `jQuery.promise()` returns a Promise object allowing you to "observe when all actions of a certain type bound to the collection, queued or not, have finished" - read more in the [jQuery documentation](https://api.jquery.com/promise/#promise-type-target). – Roamer-1888 Dec 26 '19 at 05:13
  • setInterval is the function you are looking for if you want to perform an action in a set interval https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval – fubar Dec 26 '19 at 16:02

2 Answers2

1

No, it's not a promise. It's scheduling an effect in the fx queue of the jQuery element, which can be manipulated in ways that a promise chain could not.

But yes, the result is similar enough to a promise chain that you can get a promise for the end of the animation queue using the .promise() method, and then start a real promise chain off that.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

Its definitely not a promise since its a function call. A Promise is an object with 3 different states: pending, resolved, rejected. A Promise holds methods for accessing those states: then(), catch(). The operator "." is just there to access the return value of a function. This means a function can return a Promise and you then can access the then() method of the Promise object with functionCall().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)
fubar
  • 383
  • 2
  • 11