JavaScript: Synchronous, asynchronous, and event loops

Source: Internet
Author: User
Tags event listener message queue readfile

A. Single thread

We often say that "javascript is single-threaded".

The so-called single-threaded, refers to the JS engine is responsible for interpreting and executing JavaScript code of the thread only one. You might call it the main thread.

But there are actually other threads. For example: threads that handle AJAX requests, threads that handle DOM events, timer threads, threads that read and write files (for example, in node. js), and so on. These threads may exist within the JS engine or may exist outside of the JS engine, where we do not differentiate. You might call them worker threads.

Two. Synchronous and asynchronous

Suppose there is a function a:

A (args ...);

Synchronization: If the caller is able to get the expected result (i.e. get the expected return value or see the expected effect) when function a returns, then this function is synchronous.

For example:

MATH.SQRT (2); Console.log (' Hi ');
    • When the first function returns, it gets the expected return value: The square root of 2.

    • When the second function returns, you see the expected effect: A string is printed in the console.

So both of these functions are synchronous.

Async: If the caller is not able to get the expected result when function a returns, it needs to be obtained in the future by some means, then the function is asynchronous.

For example:

Fs.readfile (' foo.txt ', ' UTF8 ', function (err, data) {    console.log (data);});

In the above code, we want to read the contents of the file Foo.txt and print it through the Fs.readfile function.

But when the Fs.readfile function returns, we expect that the result will not happen, but wait until all the files have been read. If the file is large, it may take a long time.

Here's an example of an AJAX request that looks at the difference between synchronous and asynchronous:

    • Async Ajax:

main thread: "Hello, ajax thread." Please send an HTTP request for me, I have the request address and parameters to you. ”
Ajax Thread : "OK, the main thread." I'll send it right away, but it may take some time, you can go ahead and do something else. ”
main Thread:: "Thank you, you get a response and tell me." ”
(then the main thread does something else.) After a meal of time, it received a notification of the arrival of the response. )

    • Synchronous Ajax:

main thread: "Hello, ajax thread." Please send an HTTP request for me, I have the request address and parameters to you. ”

Ajax thread : "..."
main thread:: "Hey, Ajax thread, why don't you talk?" ”
Ajax thread : "..."
main thread: "Hey! Hey, hey, hey! ”
Ajax thread : "..."
(After a moxa of fragrant time)
main thread:: "Hey! Please say something! ”
Ajax thread : "Main thread, I'm sorry, I can't talk at work." Your request has been sent out, get the response data, to you. ”

It is because JavaScript is single-threaded, and asynchronous is easy to implement non-blocking, so in JavaScript for time-consuming operations or the operation of uncertain times, the use of asynchronous is a necessary choice. Async is the focus of this article.

Three. Elements of an asynchronous process

As you can see from the above, the 异步函数 call is actually done quickly. But there are a number of steps behind the worker thread performing the asynchronous task, the notification main thread, the main thread calling the callback function, and so on. We call the whole process 异步过程 . The invocation of an asynchronous function is only a small part of the entire asynchronous process.

To summarize, an asynchronous process is usually the case:

The main thread initiates an asynchronous request, and the corresponding worker thread receives the request and informs the main thread that it has received it (the asynchronous function returns); The main thread can continue executing the following code while the worker thread executes the asynchronous task, the main thread is notified after the worker has finished the work, and the main thread receives the notification and executes a certain action (call the callback

Asynchronous functions typically have the following form:

A (args ..., CALLBACKFN)

It can be called an initiating function of an asynchronous process, or an asynchronous task registration function. args is the parameter required by this function. callbackFn It is also the parameter of this function, but it is more special, so it is listed separately.

So, from the main thread point of view, an asynchronous process consists of the following two elements:

    • Initiating A function (or called A registration function) A

    • callback function CALLBACKFN

They are all called on the main thread, where the registration function is used to initiate the asynchronous process, and the callback function is used to process the result.

To give a specific example:

SetTimeout (FN, 1000);

The setTimeout is the initiating function of the asynchronous process, and fn is the callback function.

Note: The previously stated form A (args ..., callbackfn) is simply an abstract representation and does not necessarily mean that the callback function must be the argument for the initiating function, for example:

var xhr = new XMLHttpRequest (); xhr.onreadystatechange = xxx; Add callback function Xhr.open (' GET ', url); Xhr.send (); Initiating functions

The initiating function and the callback function are separate.

Four. Message Queuing and Event loops

As mentioned above, during an asynchronous process, the worker thread needs to notify the main thread after the asynchronous operation is complete. So how does this notification mechanism be implemented? The answer is to take advantage of Message Queuing and event loops.

To summarize in a sentence:

The worker thread puts the message in the message queue, and the main thread takes the message through the event loop process.

    • Message Queuing: Message Queuing is a first-in-one-out queue that contains various messages.

    • Event Loop: The event loop is the process by which the main thread repeatedly takes messages from the message queue and executes them.

In fact, the main thread will only do one thing, that is, to take messages from the message queue, execute the message, then fetch the message, and then execute. When Message Queuing is empty, it waits until the message queue becomes non-empty. And the main thread is only going to fetch the next message after the current message has been executed. This mechanism is called the event loop mechanism, and the process of taking a message and executing it is called a loop.

The event loop is expressed in code that is probably the case:

while (true) {    var message = Queue.get ();    Execute (message);}

So, what exactly is the message in Message Queuing? The exact structure of the message is of course related to the specific implementation, but for the sake of simplicity, we can assume that:

The message is the callback function that was added when the asynchronous task was registered.

Again, for example asynchronous Ajax, suppose the following code exists:

$.ajax (' http://segmentfault.com ', function (resp) {    console.log (' I am responding: ', resp);}); /other code .....

The main thread continues to execute additional code after the AJAX request is initiated. The AJAX thread is responsible for requesting segmentfault.com, and when it gets a response, it encapsulates the response into a JavaScript object and constructs a message:

The message in Message Queuing looks like this. var message = function () {    CALLBACKFN (response);}

one of the callbackfn is the callback function in the previous code when the response was successful.

When the main thread finishes executing all the code in the current loop, it takes the message (that is, the message function) out of the message queue and executes it. At this end, the callback function is executed when the worker thread is finished with the main path 通知 . If a callback function is not provided at the beginning of the main thread, the AJAX thread does not have to notify the main thread after receiving the HTTP response, and there is no need to put the message in the message queue.

The diagram shows that this process is:

From the above we can also get the obvious conclusion that:

The callback function of the asynchronous procedure must not be executed in the current round of event loops.

Five. Asynchronous and event

The "event loop" mentioned above, why is there a? 事件 That's because:

Each message in the message queue actually corresponds to an event.

There has been no mention of a very important asynchronous process: DOM events.

For example:

var button = document.getelement (' #btn '); Button.addeventlistener (' Click ', Function (e) {    console.log ();});

From an event point of view, the code above indicates that a mouse click event Listener is added to the button, and the event listener function is invoked when the user taps the button and the mouse click event Triggers.

From the point of view of the asynchronous process, the AddEventListener function is the initiating function of the asynchronous process, and the event listener function is the callback function of the asynchronous process. When an event is triggered, the asynchronous task completes and the event listener function is encapsulated into a message queue, waiting for the main thread to execute.

The concept of an event is not really necessary, and the event mechanism is actually the notification mechanism of the asynchronous process. I think it exists for the programming interface to be more friendly to developers.

On the other hand, all asynchronous processes can also be described by events. For example, setTimeout it can be seen as an event that corresponds to a time . The setTimeout (FN, N) of the preceding article can be viewed as:

Timer.addeventlistener (' timeout ', +, FN);

Six. Producers and consumers

From the producer and consumer point of view, the asynchronous process is this:

The worker thread is the producer and the main thread is the consumer (only one consumer). The worker thread executes the asynchronous task, encapsulates the corresponding callback function into the message queue after the execution completes, and the main thread continuously takes the message from the message queue and executes it when the message queue is empty and the main thread blocks until the message queue is again non-empty.

In the Ps:ecmascript 262 specification, there is no description of the concepts and implementations of async, event queuing, and so on. These are the mechanisms used by the specific JavaScript runtime environment. The focus of this article is to describe the principles of asynchronous processes and make a lot of simplification for ease of understanding. Therefore, the use of some of the terminology may be inaccurate, the details are not necessarily correct, such as Message Queuing structure of the message. Please note the reader.

JavaScript: Synchronous, asynchronous, and event loops

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.