Promises, promises (in Javascript)

This is a short explanation of what promises are, and how they work.

You're probably familiar with callbacks, where you pass a function as an argument to another function, like this:

   f( function b() {...});

When f does something, usually taking some time, it runs b.

Promises are just callbacks with a little more structure.

There's a library called Q that's influencing frameworks like Angular. Q's most visible quality is that it uses a differen syntax:


The callbacks are set up outside of the parentheses of the call to f(), and it looks like you can chain a whole bunch of callbacks. Additionally, there are different types of callbacks - which correspond to different situations, and have different data passed to the callback.

Those methods, success, error, then, etc. are all methods that register callbacks for f().

What's happening is that f(), when run, immediately returns a promise object, which has all those specific callback methods. Each executes immediately, and saves the callback to an internal data structure that keeps callbacks organized. Each method also returns a promise object, so more promises can be made. The first promise, in turn, was created and registered as a callback on some (nonblocking) function within f().

When the promise is executed, all the registered functions are, in turn, executed (depending on things like whether it was an error or not, etc.)

If you imagine what's going on: the promises create this big data structure which has some branches that will execute (like "then"), and some that will not (like "error" and "success" callbacks). During runtime, when you need to execute a nonblocking function, like http requests, you build up these data structures with promises. Then, when the function completes, the promises are evaluated. (Not only that, but you can return a value -- you can't do that with callbacks. Think about it. Where do returned values from a callback go? Nowhere.)

Aren't these promises great?

It's better than the regular problem of nested callbacks. Promises go beyond callbacks by creating generic structures that compose callbacks. They also allow for throwing errors and returning values (which can't be done in callbacks).

There are other technologies that help with the problem, too. Threads... used threads judiciously. (You can go the entirely other direction and use too many threads, and end up with too many blocked threads. It's not available in JS, so it's a moot point.

Multiple processes with sockets communicating between them, which is like threads, but with even more isolation, is another option... if you're on the server side. It's not in JS.

There's also an argument to be made for coroutines... although it's going to confuse a lot of people. It's also not available in JS.

Angular has a event messaging system, where you can $emit and $broadcast arbitrary messages and watch them. This is an extreme decoupling of events and program behavior. It's inefficient, but worth using (again, judiciously) to decouple the parts of your application from each other.

It's all about using different technologies in different situation, so that your code doesn't get complex.