What is asynchronous programming, and why do you use it?
1. Event Loop
Before introducing asynchronous programming, let’s introduce Event loops.
We all know a single-threaded language, javascript is used to handle user interaction, the implementation of the DOM to add authorization, such as an event loop only deals with an incident response, make the execution of the script is relatively continuous, so have the event queue, used to store execution events, from where the events in the event queue push come in? This is the function of the Event Loop. The main function of the Event Loop is to push callback functions that meet certain conditions, such as timing trigger threads and asynchronous HTTP request threads, into the Event queue and wait for the javascript engine to be idle. This is the function of the Event Loop. In simple terms, there are two threads in the program. One is responsible for the program itself, which is called the “main thread”, and the other is responsible for the communication between the main thread and other threads (mainly various I/O operations), which is called the “Event Loop thread”. It belongs to a program structure, used to wait for and send message events.
2. Micro and macro tasks
After introducing Event Loop, let’s introduce microtasks and macro tasks. Execution of javascript engines have order, it will be the main thread of the mission, waiting for the main thread, the task has been completed in the micro task queue to check whether there is a small task, there is micro task executing the task, the task is done will be done in macro task queue to find whether there is a macro task, and then start a macro missions.
Macro tasks: Each event in the event queue is a macro task, such as the main code block, setTimeOut, setInterval, setImmediate, and so on: Tasks that need to be performed before the next macro task starts after the current macro task is completed can be understood as callback events, e.g. promise. then is a typical microtask, proness.nexttick, etc. Microtasks are generally completed at one time, while macro tasks require multiple event cycles to complete.
3. Asynchronous programming solution — callback functions
Callbacks are the basic solution to asynchronous programming, and in ES5, we usually use this method for asynchronous programming
Suppose you have two functions, fn1 and fn2, and the latter needs to wait for the result of the former. Normally this would be the case:
fn1();
fn2();
Copy the code
However, if fn1 is a time-consuming task, the program will be slow and the page load time will be longer, so you can consider using fn2 as the callback function of FN1
Function fn1(callback){setTimeOut(function(){//fn1 (callback); }}, 100)Copy the code
That is equivalent to fn1 (fn2) This way is simple, easy to understand, the synchronous operation into a asynchronous operations, fn1 does not block the program runs, the main logic is equal to the first executable program, will be time consuming task delay the execution, but this way will damage the code maintenance, each nested function, high coupling, the process will be chaos, If the code is too long, it is not easy to read, and only one callback function can be specified per task.
4. Asynchronous programming solution — event listening
Event listening is mainly event-driven, where the execution of tasks depends not on the order of the code but on whether an event occurs
f1.on('done', f2); 1 function f1(){setTimeout(function (){f1.trigger('done'); }, 1000); }Copy the code
In other words, if F1 is executed, f2 will be executed. The advantages of this method are easy to understand and can bind multiple events, and each event can specify multiple callback functions. Moreover, it can carry out “Decoupling”, which is good for modularity. The disadvantage is that the entire program has to be event-driven, and the flow becomes very unclear.
5. Asynchronous programming solutions — publish and subscribe
Suppose there is a “signal center”. When a task completes, it “publishes” a signal to the center. Other tasks can “subscribe” to the signal center to know when they can start executing. This is called a publish-subscribe pattern, also known as an observer pattern.
Advantages: This approach is similar in nature to “event listening”, but is significantly superior to “event listening”, because we can see how many signals exist and how many subscribers each signal has, and thus listen to the execution of the program.
Here’s an example:
// Use Ben Alman's Tiny Pub/Sub, which is a plugin for jQuery. jQuery.subscribe("done", f2); //f2 subscribe "done" signal to "signal center "jQuery. Function f1(){setTimeout(function (){jquery.publish ("done"); }, 1000); } // jquery.publish ("done") publish("done") f2Copy the code
6. Asynchronous programming solution — Promise
ES6 provides a new way to implement asynchronous programming — Promise, which allows us to implement asynchronous programming quickly and efficiently. Let’s introduce Promise first.
- Three states of Promise
Promise is an object with an asynchronous operation and a unified API to obtain the result of the asynchronous operation. It has three states: Pending, Resolved and Rejected. The three states can be changed from waiting to completed. Or you can go from waiting to rejected, irreversible, and once you go from one state to another it’s irreversible, you can’t go back.
- Parameters passed by Promise
The Promise constructor accepts as an argument a function called resolve and reject, which are called on success and reject, which pass the result of the asynchronous operation.
- Important APIS in Promise
Promise. All ((p1, p2, p3)) : Pack several Promise objects into an array. Once the promise objects are packed, the method must ensure that all promise objects are in the resolve state, while any promise object in the Reject state will be used for subsequent callbacks
Promise.race ([P1,p2,p3]) : This method does exactly the same thing as promise.all. The only difference is that if one of several promise objects is in the resolve state, it will return successfully
- Promise handles errors in three ways
A: Then (resolve,reject). The second callback in then is what you do when you fail. Catch doesn’t work
If (val,reject) => {if(val){resolve({name:' foo '},100); Reject ('404');}else{reject('404');} reject('404'); // Pass argument, error cause}}); } f(false) .then( (data, data2) => { console.log(data2); //undefined }, e => { console.log(e); If ((data,data2) => {if (data,data2) => {if (data,data2) => {if (data,data2) => { console.log(data2); // The output is undefined},e => {console.log(e); })Copy the code
B: Use catch to catch errors
If (val) {resolve(val); if (val) {resolve(val); } else { reject("404"); }}); } f(true) .then((data) => { console.log(data); //{name:' xiaoming '} return f(false); }). Then (() => {console.log(" I will never be output "); }). Then (() => {}, (e) => console.log(" failed "); //.log(e) => {console.log(e) => {console.log(e) => {console.log(e) => {console.log(e) => {console.log(e) => {console.log(e) => {console.log(e); //404}). Then (() => {console.log(e); console.log(e); return f(false); }) .catch(); // If the last catch has an error, the catch is infiniteCopy the code
The C: finally method catches errors. The content in finally must be executed whether it succeeds or fails. Even if a successful promise is returned, the following finally will also be executed, so you can use this to do some finishing work in finally.
If (val,reject) => {if(val){resolve({name:' foo '}); }else{ reject('404'); }}); } f(true) .then(data => { console.log(data); //{name:' xiaoming '} return f(false); }) .catch(e => { console.log(e) //404 return f(false); Uncaught (in promise) 404}).finally(() => {console.log(100) //100})Copy the code
- The shortcoming of Promise
The downsides of promises are that errors require a callback function to catch, that they are executed immediately once they are created without stopping, and that while in the wait state there is no way to know where we are at, whether we have just started or are close to completion.
- How does Promise implement asynchronous programming
The idea is that each asynchronous task returns a Promise object that has a THEN method that allows the callback function to be specified. For example, f1’s callback function F2 can be written as:
f1().then(f2); Function f1(){var DFD = $.deferred (); SetTimeout (function () {// f1 ddfd.resolve (); }, 500); return dfd.promise; }Copy the code
This way you can specify multiple callbacks, f1().then(f2).then(f3)… The callback function becomes chained, and the flow of the program can be seen clearly. If a task is already complete and a callback is added, the callback is executed immediately. So, don’t worry about missing an event or signal.
7. Asynchronous programming solution — Async
Async is also a solution provided by ES6.
async function fn(){return 'hello world'}
Copy the code
Async is automatically executed, and await can be either a Promise object or a primitive datatype. It returns a Promise object, and the return value is used as a parameter in the successful callback function of the Promise object’s then method
The characteristics of Async function: Await can only be placed inside Async function, which is more semantic. After await can be Promise object, also can be number, string, Boolean value, etc. As long as the Promise object state changes to reject after await statement, the whole Async function will stop execution.
Async function handling error:
Try… Catch catches an error, because an await is followed by a Promise and an exception is caught by a catch inside a Promise, and an await is a syntactic sugar of a then and does not catch an exception, so we need to use a try… An error is caught and the corresponding logic is processed
Async implements asynchronous programming:
Function sleep(timeout) {return new Promise((resolve) => {setTimeout(resolve, Async function test() {console.log('test start') await sleep(1000) console.log('test end')} console.log('start') test() console.log('end')Copy the code
JavaScript to achieve asynchronous programming on the way to introduce so much, summed up a few hours, also belong to cross the sky completed, ha ha ha ha ha, I think Promise to achieve asynchronous programming better, each has its own benefits, master these questions in the face of the interviewer must be no problem!