3

When programming with promises in jQuery, I sometimes need to start out with a resolved promise, particularly when chaining .then() in a loop like this as illustrated in Method #2 in this answer:

data.reduce(function(p, item) {
    return p.then(function() {
        return print(item);
    });
}, $.Deferred().resolve().promise());

So, I know I can get a resolved promise with this:

$.Deferred().resolve().promise()

But, that seems kind of ugly and wasteful (three function calls). Is there a better (less code, fewer function calls) way to get a resolved promise in jQuery or a better way to write my .reduce() loop above?

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979

1 Answers1

3

For starters - you don't need the .promise. jQuery deferred objects are already also promises so $.Deferred().resolve() will also work.

In my opinion it is the best approach with jQuery since it is explicit, however there are shorter ways around it. The shortest one I know is:

$().promise(); // shorter but more hacky.

$.Deferred().resolve(); // this will work and is what I'd do

$.when(); // this is also a viable alternative 

Which is reasonably short. Of course, it is probably best to use a better promise library when one is able since jQuery promises do not guarantee well ordered asyncrhonous execution and does not allow error handling in addition to being very slow if you have many promises running.

Of course, no one is keeping you from writing a utility method around it :)

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • Hmmm. I swear I looked at one point and a jQuery Deferred didn't have `.then()` - only a promise did. Weird - not sure where I got that notion. It does seem to work as a thenable now though. OK, that reduces one function call. I agree that I don't like `$().promise()` as that just seems to hacky. – jfriend00 Aug 03 '14 at 06:48
  • 1
    On a separate note, do you really have to trash jQuery promises in almost every post where the topic comes up? I use promises that jQuery generates (like from Ajax calls) so I don't really care to import yet another promise library which isn't fully interoperable with the promises jQuery creates (regardless of who's fault that is). – jfriend00 Aug 03 '14 at 06:49
  • @jfriend00 I'm sorry if it sounds rude and I do use jQuery promises myself sometimes but I wholeheartedly believe jQuery's promise implementation is absolutely horrible. I've seen developers fall in its pits more than once or twice and I'll suggest alternative implementations or native promises to people whenever I can. I've seen someone bitten by jQuery promises in an example just like your reduce just last week when the code after the `.reduce` executed before the reduce'd `.then` sometimes because of it and it took them half an hour to find. I'd like to warn people whenever I can. – Benjamin Gruenbaum Aug 03 '14 at 06:53
  • 1
    I think it would be more appropriate if you saved your recommendation of switching to another promise library and trashing of jQuery's promise implementation to times when a difference in implementation was particularly relevant to the particular issue being discussed, not just because someone mentioned jQuery promises in their question. – jfriend00 Aug 03 '14 at 07:01
  • Your thoughts have been noted. I understand and respect them. I answer promise questions in order to promote that technology and help people who are struggling with it, I wouldn't feel easy providing a solution without mentioning that common pitfall. Especially when I saw it in the exact same scenario just last week. You're aware of it but you're also probably aware of the fact you're not the only one reading this answer. I did not write over 200 answers about promises only to promote people falling into that pit. Thanks for the comment though I'll keep that in mind and be more subtle. – Benjamin Gruenbaum Aug 03 '14 at 07:22