Asynchronous programming in Javascript is gradually being accepted by everyone. Previously, people usually implemented it through callback nesting, setTimeout, setInterval, etc. The code looks very unintuitive, and it is difficult to understand quickly without looking at the entire code logic. Asynchronous functions in Javascript probably include I/O functions (Ajax, postMessage, img load, script load, etc.), timing functions (setTimeout, setInterval), etc.
We are all familiar with these. In complex applications, there are often multiple layers of nesting, and even some steps are not completed, causing program exceptions. The simplest example: for example, if you inject a node into the DOM, you must wait for the node. After the injection, the node is operated. When a large number of nodes are injected, the time is often difficult to grasp. If our code relies on third-party API data. We have no way of knowing the latency of an API response, and other parts of the application may be blocked until it returns a result. Promises provide a better solution to this problem, being non-blocking and completely decoupled from the code.
So, let me take a look at asynchronous programming in Javascript. First, I recommend that you take a look at the relatively popular Promises/A specification.
Promises/A specification
Note: For ease of understanding, the description may be different from the Promises/A specification;
CommonJS’s Promises/A specification simplifies asynchronous programming by standardizing API interfaces, making our asynchronous logic code easier to understand.
We call implementations that follow the Promises/A specification a Promise object. Promise objects have and only have three states: unfulfilled (unfulfilled), fulfilled (completed), failed (failed/rejected); when initially created, unfulfilled (unfulfilled) status, the status can only change from unfulfilled (unfulfilled) to fulfilled (completed), or unfulfilled (unfulfilled) to failed (failed/rejected). Once the status becomes fulfilled (completed) or failed (failed/rejected), the status cannot be changed again.
The Promises/A specification provides a solution for describing the concept of delay (or future) in a program. The main idea is not to execute a method and then block the application to wait for the result to be returned before calling back other methods, but to return a Promise object to satisfy future listening. Both fulfilled and failed states can be monitored. Promise registers callbacks by implementing a then interface to return a Promise object:
Thethen interface is used to monitor the different states of a Promise. fulfilledHandler is used to monitor the fulfilled (completed) status, errorHandler is used to monitor the failed (failed/rejected) status, and progressHandler is used to monitor the unfulfilled (not completed) status. Promise does not force the implementation of unfulfilled (unfinished) event monitoring (for example, we know that the Deferred of the old version of jQuery (1.5, 1.6) is a Promise implementation, but it does not implement monitoring of the unfulfilled (unfinished) state and calls back the progressHandler).
It is generally believed that the then interface returns a new Promise object instead of the original Promise object. This new Promise object can be understood as a view of the original Promise object. It only contains the original Promise object. A set of methods that can only observe the state of the original Promise object but cannot change the internal state of the deferred object. This can avoid conflicts between multiple callers, and multiple callers can change the state of the new Promise object without affecting other callers.
In addition, Promise provides two interfaces to implement state transition: resolve (implementation status changes from unfinished to completed) and reject (implementation status changes from unfinished to rejected or failed).
Send a picture to help understand:
With Promise, you can write asynchronous logic with synchronous thinking. In an asynchronous function, you cannot use try/catch to catch exceptions, nor can you throw exceptions. With Promise, we can explicitly define errorHandler directly, which is equivalent to catching exceptions.
The following are several class libraries that follow the Promises/A specification, when, q, rsvp.js, jQuery.Deferred, etc.