However… We’re not there yet, and it’s frustrating me nearly every day.
I work in several different projects and runtime environments, and I have to deal with a lot of different promise libraries because of this. The result: a constant learning and re-learning battle, because every Promise library does something slightly different than the others, even when the libraries in question are written to the same Promise spec.
Let’s look at how you create and resolve a promise in q.js, RSVP.js, WinJS, and jQuery. But before I look at them, I want to let every author and contributor to each of these libraries know that I really do appreciate the work they’ve put in. I use these libraries (or have used them in the past, in the case of WinJS) with great effectiveness in my applications. My code is far better for having put the time and effort in to each of these libraries. The inconsistencies, though, are killing me.
q.js: Deferred Objects And Promises
I’ll start with q.js because I’m using it in one of my projects and it’s on my mind at the moment.
Q uses the idea of a “deferred” object to handle the real processing and the promise is only the public API of the promise. You should note that q does not allow you to call
.then() or other “promise” methods on the deferred object, though. You can only call those on the promise itself.
jQuery: Deferred Objects And Promises
Q is quite similar to jQuery’s idea of a promise. I honestly don’t know if there is a relationship / influence between q and jQuery, but there certainly looks to be on the surface. The same code in jQuery, though, is just different enough to frustrate you endlessly.
The major difference here, is that q does
deferred.promise; while jQuery does
deferred.promise(). jQuery Deferred objects also let you call
.then() and other “promise” functions on the deferred object itself, unlike q.
RSVP: Just Promises
Next up is RSVP. I’m also using this in a current project. It was brought in to my code through the use of another service in this project. I generally like RSVP as much as I like other Promise libraries – that is to say, I sing the praises of promises quite regularly and RSVP is great.
RSVP has yet another API for creating an manipulating promises and it is dramtically different than q or jQuery in how you get a promise up and running.
If you’ve never seen RSVP (or WinJS – coming up next) this may be confusing. You are not allowed access to a
.resolve() method on an object instance. Instead, you must provide a callback function to the Promise constructor function. This callback receives a resolve and reject parameter, which are themselves functions. The
resolve method is the equivalent of
deferred.resolve() in the previous q and jQuery examples.
Great. Yet another odd syntax that makes me do things in a strange place this time. I might see the point of this, in that you don’t have to worry about where the “public” API is. The only way to resolve the promise is within the callback function that the promise ran when it was created. But this is completely different than q or jQuery. It took me a bit to realize that I was not allowed to have a deferred object to resolve at a later point. I must put all my code to determine when to resolve or reject the promise, within the promise callback – or at least call out to a method that can determin this for me, to keep the code clean.
WinJS: Just Promises
Other than the
RSVP parent namespaces, WinJS and RSVP’s APIs are pretty much interchangeable. I think there are some slight difference in other areas of the API, though, such as which methods WinJS provides for wrapping code in a promise, or providing progress updates, etc. I’m not sure if these difference fall in to our out of a given Promise spec, though.
Please Clean This Up
Yes, I get that there are different needs in different situations. Some libs will have extra things. That’s awesome. But for the parts that are supposed to be the same, please make them the same – all the way around, from constructor function to method signatures and expected behaviors. Frankly it doesn’t matter to me all that much, which spec wins. Just make it consistent across all the promises libraries. There are far too many inconsistencies in promises, at this point.
Need To Learn More About Promises?
If you’re looking to wrap your head around these powerful objects, check out WatchMeCode Episode 13: Promises From The Ground Up.