1

Given the code using Promise constructor

let promise = () => new Promise(resolve => resolve(1));

new Promise((resolve, reject) => {
  setTimeout(() => reject("10 seconds exceeded"), 10000);
  resolve(promise())
})
.then(data => console.log(data))
.catch(err => console.error(err));

1 is logged at console

Given the equivalent code using jQuery.Deferred the jQuery.deferred object is logged at .then(), not the value passed to jQuery.deferred.resolve

let promise = () => new $.Deferred(dfd => dfd.resolve(1));

new $.Deferred(dfd => {
  setTimeout(() => dfd.reject("10 seconds exceeded"), 10000);
  dfd.resolve(promise());
})
.then(data => console.log(data))
.fail(err => console.error(err));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>

though passing jQuery.deferred promise object to .then() does return expected result

let promise = () => new $.Deferred(dfd => dfd.resolve(1));

new $.Deferred(dfd => {
  setTimeout(() => dfd.reject("10 seconds exceeded"), 10000);
  promise().then(data => dfd.resolve(data));
})
.then(data => console.log(data))
.fail(err => console.error(err));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>

Is the output a jQuery bug relevant to jQuery's implementation of Promise and the specification?

guest271314
  • 1
  • 15
  • 104
  • 177

1 Answers1

1

It's not a bug, but it might be a missing feature. jQuery never attempted to implement the standard Promise constructor, and its Deferred constructor does something quite different. Admittedly, if resolve actually fulfills, they definitely mess with the standard terminology; again however jQuery's implementation does predate the standard so it's not surprising.

Is the output a jQuery bug relevant to jQuery's implementation of the Promise/A+ specification?

No, the Promise/A+ specification is only concerned with the behaviour of the then function, not the promise construction. There were indeed many inherent problems with that in jQuery's promise implementation, but since version 3 those have been fixed at least (which can be tested), so jQuery promise instances are now interoperable with all other implementations.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • @guest271314 That just means that things like `Promise.resolve(jQuery.Deferred(…).then(x => Promise.resolve()))` work out of the box, which makes it easy to drop jQuery and use a proper implementation instead. – Bergi Sep 29 '17 at 17:44
  • Am aware that you cannot represent why the jQuery implementation decided to implement or not implement a feature, though do you have any indication that the jQuery authors and contributors are aware of the glaring difference between `Promise` pattern and `jQuery.Deferred()` pattern? _"No, the Promise/A+ specification is only concerned with the behaviour of the `then` function"_ Is not `.then()` expected to have the value of the `Promise` available, and not the `Promise` object itself? That is, is the `jQuery.deferred.then` implementation in compliance with the specification? – guest271314 Sep 29 '17 at 17:46
  • Certainly the results at `jQuery.deferred.then` are inconsistent with the output of using the same pattern with native `.then()` – guest271314 Sep 29 '17 at 17:50
  • @guest271314 Yes, everyone is aware of the glaring differences between the deferred and the promise constructor pattern (and `resolve` not resolving but fulfilling is just another), but I don't know of any intentions to do something about it. Yes, jQuery-v3's `then` is in compliance with the specification - it calls the callback with whatever value the promise was fulfilled with. There is more than one implementation that allows to fulfill promises with other promise objects (though ES6 is not one of them). – Bergi Sep 29 '17 at 17:52
  • _"it calls the callback with whatever value the promise was fulfilled with"_ Here we resolve `1`, though the jQuery deferred or promise object is the fulfillment value at `.then()`. Curious why you state that the jQuery implementation is not a bug? Why would one expect a jQuery deferred or promise object and not the value resolved at a jQuery deferred at chained `.then()`? – guest271314 Sep 29 '17 at 17:55
  • 1
    @guest271314 You did not resolve with `1`, you `.resolve`d with the return value of `promise()`. Apparently jQuery took that as the fulfillment value directly. There is nothing that says this should work differently - apart from the naming discrepancy `resolve` vs `fulfill` - as there is no spec for deferreds. – Bergi Sep 29 '17 at 18:14