5

What are the differences between Mozilla's JavaScript docs' Promises (see API page) and jQuery's Promises (see API page)?

Mozilla's promise seems to have only 2 methods: then and catch. jQuery's promise seems to have more methods, including: then, done, and fail. (from here)

How come the JS API on Mozilla doesn't have done()? What if I want to have a done() functionality in JavaScript? What do I do?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Melissa
  • 1,236
  • 5
  • 12
  • 29
  • 2
    jQuery's promises don't really follow the spec at all, and is something cooked up for a library, there's nothing that says they have to be even remotely the same (and they aren't), or have the same methods. – adeneo Dec 22 '15 at 02:51
  • 1
    jQuery is just a bike riding on Javascript's road. If Javascript suddenly decides to paint its road in peanut butter, that's what it will do. jQuery will just have to get a bike that rides in peanut butter. – Alex McMillan Dec 22 '15 at 02:58
  • 1
    @Alex McMillan: " jQuery is just a bike riding on Javascript's road. If Javascript suddenly decides to paint its roads in peanut butter, that's what it will do. jQuery will just have to get a bike that rides in peanut butter." What? (LOL) That's the funniest thing I've ever read on SO. Can you explain your thoughts further in an answer or something? Thanks! – Melissa Dec 22 '15 at 03:00
  • 1
    @Melissa jQuery is just a library. jQuery is WRITTEN in Javascript, and does nothing more than provide a few helpful functions that do things like abstract away browser inconsistency... think of Javascript as the class and jQuery as the object *instantiated* from the class. Javascript is the ruler, jQuery is the peon. – Alex McMillan Dec 22 '15 at 03:02
  • 2
    If I buy ham from a butcher and start selling it as "BACON SANDWICHES", I can't expect the butcher to suddenly rename his ham "Bacon". – Alex McMillan Dec 22 '15 at 03:04
  • If you have a twitter account I want to follow it. – Melissa Dec 22 '15 at 03:08
  • Note that the MDN page you link to isn't documenting "Mozilla's API", it is documenting the Promise object that is part of the JavaScript language as of the ECMAScript v6 spec. – nnnnnn Dec 22 '15 at 03:12
  • @nnnnnn I've fixed the wording. Is this better? – Melissa Dec 22 '15 at 03:14

3 Answers3

3

Mozilla's javascript promises are based on ES6 standard, whereas jQuery promises were something created before ES6 was released.

Based on my reading of the jQuery docs, ES6 then is equivalent to jQuery done.

There are actually a boatload of promise libraries, but to me the ES6 one is the simplest to understand. You don't need more than "then" and "catch" and it is real easy to chain together into a sequence of operations. Add to that with Promise.all for parallel tasks and 99% of what you need is covered.

return doSomething().then(function(result) {
  return doSomethingElse(result);
}).then(function(secondResult) {
  return doThirdSomething(secondResult);
}).catch(function(err) {
  console.log(err);
}).then(function(finalResult) {
  // a then after a catch is like a "finally" or "always"
  return finalResult;
}); 

Some things that jQuery does support that is not in ES6 is some sort of "progress" resolve.

Steve Campbell
  • 3,385
  • 1
  • 31
  • 43
3

jQuery's deferred API is bloated and predates promise libraries. Once they realised how useful promises were, they added a then (or previosly, pipe) method, however it they failed to get it 100% right.

How come the JS API on Mozilla doesn't have done()?

It's completely unnecessary. All Promises/A+ compatible implementations (which includes ES6) only need a single method: .then(). It's completely universal, you can do everything with it - it's the primitive of promises.

What if I want to have a done() functionality in JavaScript? What do I do?

Well, you could implement it yourself:

Promise.prototype.done = function(cb) { // or function(...cbs) for (let cb of cbs) …
    this.then(cb).then(null, function(err) { /* ignore */ });
    return this;
};

But as you can see from that, it's not very useful actually. It doesn't chain, and it ignores exceptions, so you should just use then everywhere.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks! Please see the updated question at the bottom of my question. – Melissa Dec 22 '15 at 15:57
  • Just asking a new question would've been enough, there's no reason to update this one - or at least I cannot see any commonality between jQuery's `done` usage and breaking from chains. Btw, searching for `[promise] break chain` would've brought many valuable results already – Bergi Dec 22 '15 at 19:04
  • Good heavens - what a world of confusion learning this stuff on internet has been since jquery deferred objects and native js promises can look identical in psuedoish-code examples. Not to mention blue-bird adding another whole layer of subtle nuances to sort out in your head. – Nick Pineda May 03 '16 at 21:57
0

I can speak for why ES6 don't have .done. However, you can still have something that's akin to .done.

yourPromiseObject.then(successHandler).catch(failureHandler).then(doneHandler);

The first then handles a success response, but will not be called with the yourPromiseObject's function rejects or throw exception. The second catch is critical in "resolving" any exceptions/rejection (in short, you tell the promise object to keep going, you know that there's an error). Make sure you return something valid, even something as simple as the failureHandler consist of nothing but a return 0 will work. The final .then is now guaranteed to be called, so that's your .done

ShuberFu
  • 689
  • 3
  • 15