Is the following jQuery code equivalent to how it is done in ES6's way, or should the jQuery way be written differently?
// ES6:
new Promise((resolve, reject) => {
console.log("start");
setTimeout(() => resolve("a"), 2000);
}).then(s => {
console.log(s);
return new Promise((resolve, reject) => {
setTimeout(() => resolve("b"), 2000);
});
}).then(s => {
console.log(s);
return new Promise((resolve, reject) => {
setTimeout(() => resolve("c"), 2000);
});
}).then(s => {
console.log(s);
});
// jQuery:
let d = $.Deferred();
d.then(s => {
console.log(s);
let d = $.Deferred();
setTimeout(() => d.resolve("b"), 2000);
return d.promise();
}).then(s => {
console.log(s);
let d = $.Deferred();
setTimeout(() => d.resolve("c"), 2000);
return d.promise();
}).then(s => {
console.log(s);
})
console.log("start");
setTimeout(() => d.resolve("a"), 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
It seems:
- Not everything can be written in one statement in jQuery. The executor has to be moved out as separate statements in jQuery.
- For jQuery, not only promise needs to be involved. The deferred needs to be used, because otherwise there is no way to resolve the promise.
- In jQuery, the line
return d.promise();
can just bereturn d;
, but is it good to return the deferred? The code that receives the deferred can inadvertently resolve the promise, but if it is chained promises, can any code actually receive the deferred and inadvertently resolve the promise?
Per @Tomalak and @jfriend00's comment, it is found that jQuery's promises can be written this way, similar to ES6 promises:
// jQuery:
$.Deferred(d => {
console.log("start");
setTimeout(() => d.resolve("a"), 2000);
}).then(s => {
console.log(s);
return $.Deferred(d => {
setTimeout(() => d.resolve("b"), 2000);
});
}).then(s => {
console.log(s);
return $.Deferred(d => {
setTimeout(() => d.resolve("c"), 2000);
});
}).then(s => {
console.log(s);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Instead of function(resolve, reject)
, it is function(deferred)
.
The jQuery.Deferred method can be passed an optional function, which is called just before the method returns and is passed the new deferred object as both the this object and as the first argument to the function.
The passed in deferred is the same as this
only if it is a traditional function but not an arrow function. But I think it will be better to use the passed in deferred d
instead of using this
.