In website development, asynchronous events are a part of the project that must be dealt with, and because of the rise of front-end frameworks, SPA implemented through frameworks is already a standard configuration for quickly building websites. It has become an indispensable part; this article will talk about the asynchronous processing method in Javascript.
Synchronization? asynchronous?
First of all, of course, we must first understand what synchronous and asynchronous mean.
These two nouns are always confusing for beginners. After all, the literal meaning of Chinese is easy to be reversed. It is doing one thing at a time, and asynchronous is the processing of many things together in parallel.
For example, when we go to the bank to handle business, queuing in front of the window is synchronous execution, and getting the number to do other things first is asynchronous execution; through the characteristics of Event Loop, asynchronous events in Javascript can be executed Easy to say
So what is the way to handle asynchronous events in Javascript?
Callback function
What we are most familiar with is the callback function. For example, the event listener registered when the web page interacts with the user needs to receive a callback function; or various functions of other Web APIs such as setTimeout
, xhr
, also need to receive It can be triggered at the time requested by the user by passing a callback function. First look at an example of setTimeout
:
// callback function withCallback() { console.log('start') setTimeout(() => { console.log('callback func') }, 1000) console.log('done') }withCallback() // start // done // callback func
After setTimeout
is executed, after the specified time interval, the callback function will be placed at the end of the queue, and then wait for the event loop to process it .
Note: Because of this mechanism, the time interval set by the developer for
setTimeout
is not exactly equal to the time elapsed from execution to trigger. Use Pay special attention when
Although callback functions are very common in development, there are also many unavoidable problems. For example, because the function needs to be passed to other functions, it is difficult for developers to control the processing logic in other functions; and because the callback function can only cooperate with try ... catch
to catch errors, it is difficult to control when asynchronous errors occur; in addition There is also the most famous “callback hell”.
Promise
Fortunately, Promise appeared after ES6, saving the developers trapped in hell. Its basic usage is also very simple:
function withPromise() { return new Promise(resolve => { console.log('promise func') resolve() }) } withPromise() .then(() => console.log('then 1')) .then(() => console.log('then 2')) // promise func // then 1 // then 2
What was not mentioned when discussing Event Loop before is that in the HTML 5 Web API standard, Event Loop adds a new micro task queue (micro task queue), and Promise is passed The microtask queue is used to drive it; the triggering timing of the microtask queue is when the stack is emptied, the Javascript engine will first confirm whether there is anything in the microtask queue, and if there is any, it will be executed first, and new tasks will not be taken out of the queue until it is emptied onto the stack.
As in the above example, when the function returns a Promise, the Javascript engine will put the function passed in later into the microtask queue, repeat the cycle, and output the above results. The subsequent .then
syntax will return a new Promise, and the parameter function will receive the result of the previous Promise.resolve
. With this function parameter passing, developers can pipeline Asynchronous events are processed sequentially.
If you add setTimeout
to the example, you can understand the difference between microtasks and general tasks more clearly:
function withPromise() { return new Promise(resolve => { console.log('promise func') resolve() }) } withPromise() .then(() => console.log('then 1')) .then(() => setTimeout(() => console.log('setTimeout'), 0)) .then(() => console.log('then 2')) // promise func // then 1 // then 2 -> microtasks are executed first // setTimeout
In addition, the aforementioned asynchronous errors that are difficult to handle with the callback function can also be caught by the .catch
syntax.
function withPromise() { return new Promise(resolve => { console.log('promise func') resolve() }) } withPromise() .then(() => console.log('then 1')) .then(() => { throw new Error('error') }) .then(() => console.log('then 2')) .catch((err) => console.log('catch:', err)) // promise func // then 1 // catch: error // ...error call stack
async await
Since the advent of ES6 Promise, asynchronous code has gradually changed from callback hell to an elegant function pipelining, but for developers unfamiliar with�, just changed from callback hell to promise hell.
The new async
/await
is regulated in ES8, although it is just a syntactic sugar combining Promise and Generator Function, but through async
/await
can handle asynchronous events with synchronous syntax, just like an old tree with new flowers, and the writing style is completely different from Promise:
function wait(time, fn) { return new Promise(resolve => { setTimeout(() => { console.log('wait:', time) resolve(fn ? fn() : time) }, time) }) } await wait(500, () => console. log('bar')) console.log('foo') // wait: 500 // bar // foo
By wrapping setTimeout
into a Promise, and then using the await
keyword to call, you can see that the result will be synchronously executed firstbar
, and then foo
appears, that is, the asynchronous event is written as synchronous processing mentioned at the beginning.
Look at another example:
async function withAsyncAwait() { for(let i = 0; i console. log(i)) } }await withAsyncAwait() // wait: 0 // 0 // wait: 500 // 1 // wait: 1000 // 2 // wait: 1500 // 3 // wait: 2000 // 4
The withAsyncAwait
function is implemented in the code, and the for
loop and the await
keyword are used to repeatedly execute wait
function; when executed here, the loop will wait for a different number of seconds in sequence each time before executing the next loop.
When using async
/await
, since the await
keyword can only be executed in async function, be sure to Remember to use both.
In addition, when using a loop to handle asynchronous events, it should be noted that many Array methods provided after ES6 do not support the syntax of async
/await
, if here Replace for
with forEach
, and the result will be executed synchronously, printing out numbers every 0.5 seconds:
Summary
This article briefly introduces the three ways Javascript handles asynchrony, and illustrates the execution order of the code through some simple examples; echoing the event loop mentioned above, the concept of microtask queue is added to it. I hope to help you understand the application of synchronous and asynchronous.
For more programming-related knowledge, please visit: Introduction to Programming! !
The above is the detailed content of understanding the asynchronous processing method in Javascript. For more information, please pay attention to other related articles on 1024programmer.com!