Does jQuery.Deferred have a bug when a jQuery.Defe

2019-07-29 19:32发布

问题:

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?

回答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.