Our first introduction to promises and $q left most of us in a serious state of “?huh?”. After asking a couple of mentors and still not feeling like I had even a tenuous grasp, I was starting to worry. But then we were graced with Ryan Shaw’s leadership!
Promises are the uniquely human way of ordering the future.
The Point of Promises
JavaScript is a single-threaded, asynchronous language. What this means is that JavaScript is only going to do one thing at a time, but it can do things in a non-linear fashion. Think of it like your eyes. You can really only focus on one thing at a time (i.e., single-threaded) but if something moves in your peripheral vision or someone touches your shoulder, or you hear a siren while you’re driving you can change what single-thing you focus on in whatever direction you desire (i.e., asynchronous).
When JavaScript executes code that does not immediately return data, the code can be run with a promise. At it’s root, this lets JavaScript offload a time-consuming process. Think of a foot race - JavaScript is basically the person with the gun who triggers the runners to do their thing, but that person is not a runner.
When JavaScript runs code as a promise, a range of things can happen. First, there is the possibility to return data immediately, in other words the function basically says “I don’t want to hold up the thread queue, so here’s something for you to work with while your request is processed.” Second, there is the possibility to return data upon successful completion of the promise, for example, here’s the dataset you requested. And finally, there is the possibility to return data upon failure to complete the promise.
So far, this should make sense, if it doesn’t, I recommend you go read Promises in AngularJS, Explained as a Cartoon by Andy Shora, before continuing.
A promise is a cloud; fulfillment is rain.
Promises versus $q
Our previous instructor and the mentors that I had sought guidance from had all done an admirable job of describing the point of promises. But when it came to the code, well, it felt like they were playing a shell game and I was definitely not following the coin!
The problem for me boiled down to why .then
was enough in some cases and in other cases why we needed $q
and deferred
. Ryan bounced around trying to explain it to us, but in the end I think I got it.
There are two different sides to each promise: the promiser (i.e., the called function) and the promisee (i.e. the calling function). Think of it like someone promising to pay you. The person making the promise is the promiser, you are the promosee. The promiser makes a promise that when some action is complete they’ll pay you, until then
they have deferred
the promise. Meanwhile, you’re already making plans for your riches, but you’ve got to wait until the promise has been completed and .then
you can actually spend the money.
If I understand this correctly, $q
is just one library that can handle the deferred aspects for a promiser.
A promise made is a debt unpaid.