In real life, the one away from computers (yes, there is something more out there), we often talk about promises. You ask people to make you a promise or you’re asked by others to promise something. Intuitively, a promise is a commitment derived from a request you make to ask a person to perform a given action at some point in the future. Sometimes the action can be executed very soon; sometimes you have to wait for a while. In an ideal world, a promise would always be kept. Unfortunately, our world is far from being ideal, so it happens that a promise is sometimes unfulfilled, no matter the reason. Regardless of the time it’ll take and the final result, a promise doesn’t block you from doing something else in the meantime like reading, cooking, or working.
In JavaScript, a promise is exactly this. You request a resource from another website, the result of a long calculation either from your server or from a JavaScript function, or the response of a REST service (these are examples of promises), and you perform other tasks while you await the result. When the latter becomes available (the promise is resolved/fulfilled) or the request has failed (the promise is failed/rejected), you act accordingly.
The previous description has hopefully given you a good understanding of what promises are. But they have a much more formal definition. Promises have been widely discussed and such discussions have resulted in two proposals: Promises/A and Promises/A+. It’s important that we discuss these two proposals before delving into the jQuery way of dealing with promises so that you can have a better understanding of promises as a concept.
The specifications of Promises/A+ can be found, but in summary, they define a promise in this way:
A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.
Promises/A+ specifications
The then() method described by the Promises/A+ proposal is the core of promises. The then() method accepts two functions: one to execute in the event that the promise is fulfilled and the other if the promise is rejected. When a promise is in one of these states, regardless of which one, it’s settled. If a promise is neither fulfilled nor rejected (for example, if you’re still waiting for the response of a server calculation), it’s pending.
Even if the formal definition mentions asynchronous operations, it’s worth noting that a promise can also be resolved or rejected by a synchronous operation, so you can use promises for more than Ajax requests, as we’ll discuss in detail later in this lesson.
Sometimes the operation, either synchronous or asynchronous, may already be completed and thus the value returned or the reason why the promise was rejected is already available. In this case, if you register a function using the then() method, this function will be executed immediately. This is another important difference between how promises act compared to callback functions in response to an event. Remember that if you add a handler for an event that has already been fired, the callback won’t be executed.
Now that you’ve read about promises and the then() method, it’s crucial that you understand why promises are so good and why they can help you in your work. To prove it, we’ll discuss and solve a simple scenario, similar to others you might encounter in your job. We’ll first approach the problem using the knowledge you’ve acquired so far, such as callback functions, and then we’ll iterate on the code to help you reach a better solution in terms of readability and maintainability by using promises.
Let’s say that you’re building a web page that uses a third-party web service called Randomizer. This service provides an API that returns a random number every time it’s called. You want your web page to retrieve two numbers and sum them. Once finished, you want to show the result in an element having content as its ID. To accomplish this goal you need to perform two Ajax requests, synchronize the callback functions in some way (you’ll use a support function), and finally show the result. The most complex part of the code is the second: the synchronization of the two independent Ajax requests.
The code of the web page we’re discussing is shown in the following listing. Please note that executing this page won’t give you any result because you’re performing requests to a nonexistent Randomizer service, but the code developed will help you in understanding the importance of promises.
Listing 13.1. Implementing multiple asynchronous operations with callbacks


The previous listing is pretty simple but it has a big issue: you need to introduce a variable for every callback function. In this case you need only two, but as the project grows, the situation could become unmanageable. In addition, let’s assume that the previous code was the body of a function invoked by another function called foo. How could you return the result of the two Ajax requests to the foo function? With the current approach, you can’t without introducing some global variables. Finally, what if you had to make two Ajax requests, with the second starting after the first is completed? In this case, you’d need to have a callback inside a callback. With more and more callbacks coming into play, the code would become a complete mess, and that’s why this situation is known as the “callback hell.”
The example discussed has given you an idea of what the problem is with callback functions. You can improve this code using promises, resulting in several advantages. ECMA International, the group behind the JavaScript specifications, has decided to introduce promises in the next version of JavaScript (ECMAScript 2015, also known as ECMAScript 6) and to adhere to the Promises/A+ proposal. Some modern browsers already support them, but others don’t and older browsers never will. Therefore, if you want to write clean, readable, and maintainable code by using the promises approach, you need to rely on a polyfill or a library in case you want more functions than those offered by the standard.
jQuery helps you avoid all these browser issues but, depending on the version of the library you’re using, it might do it in a slightly different manner. jQuery provides you with two objects, Deferred and Promise, that you can reliably use in your projects. But before we introduce them, we need to split the discussion in order to help you to easily follow the concepts of this lesson.
jQuery’s 1.x and 2.x implementation adheres to the CommonJS Promises/A proposal that was used as a base for Promises/A+. Therefore, there are differences in how you can use promises in pure JavaScript and in jQuery 1.x and 2.x. Moreover, because jQuery follows a different proposal in these branches, the library is incompatible with other ones. The Promises/A proposal defines a promise in this way:
A promise represents the eventual value returned from the single completion of an operation. A promise may be in one of the three states, unfulfilled, fulfilled, and failed. The promise may only move from unfulfilled to fulfilled, or unfulfilled to failed.
Promises/A specifications
As you can see, the terminology for the Promise object’s definition, illustrated in figure 13.1, is a bit different. The Promises/A proposal defines the unfulfilled, fulfilled, and failed states, whereas the Promises/A+ proposal uses the pending, fulfilled, and rejected states.
Figure 13.1. The terminology differences of the Promises/A and the Promises/A+ proposals

These proposals outline the behavior of promises and not the implementation, so libraries implementing promises have a then() method in common but may differ for other methods exposed.
In jQuery 3.x the interoperability with a standard promise (as implemented in ECMAScript 2015, which follows the Promises/A+ proposal) has been improved. The signature of the then() method is still a bit different for backward compatibility but the behavior is more in line with the standard. Don’t worry if this is confusing at first; we’ll highlight all the differences and also provide you with many examples.
In the next section, you’ll learn more about the Deferred and Promise objects and, where necessary, we’ll also highlight other differences between the Promises/A and the Promises/A+ proposals.
Leave a Reply