An overview of the

Many of you have seen Philip Roberts’ talk on Event Loop at JS-conf.

This article is used to record the feelings.

The term

Call Stack

Call stack: This is a data structure (last in, first out) used to record function calls. When we call a function, we push it onto the stack, and when a function returns, we push it off the top of the stack. Note also that the synchronized code is then immediately placed on the Call Stack in order. “Asynchronous Code” will be discussed later.

If the stack is occupied for a long time or blocked it can cause what we call a blocking script.

Look at this code: We understand the execution of the Call Stack.


function foo (b) {
  var a = 5
  return a * b + 10
}

function bar (x) {
  var y = 3
  return foo(x * y)
}

console.log(bar(6)) // 100
Copy the code

// The process is as follows: 1. First find the main function to be executed 2. The code is executed from console.log(bar(6)), which is pushed to the bottom of the call stack. Bar () is then pushed to the top of console.log(bar(6)) 4. Foo () is then pushed to the top of bar(), but when it returns immediately after execution, it is pushed off the stack. 6. Finally, it is ejected at console.log(), printing the return value of 100 on the output console.Copy the code

The following example of an error stack might make it clearer:

Sometimes when we recursively call a function multiple times, we end up in an infinite loop. Chrome, on the other hand, has a limited Stack size (16000 frames), so it throws a Max Stack error.

Heap

Heap: Objects are allocated in the heap. When we talk about heap memory we need to know about stack memory, reference types, basic types.

Reference type, the value size is not fixed, the stack memory store address to the heap memory object. Access is by reference. As shown in the figure below, stack memory only holds the access address of the object, and heap memory allocates space for this value. Because the size of such values is not fixed, they cannot be stored in stack memory. But the memory address size is fixed, so you can keep the memory address in the stack memory. Thus, when querying variables of reference types, the memory address is read from the stack and then the value in the heap is found from the address. For this, we call it access by reference.

Quene

Queue: The JS runtime contains a message queue, which is a list of messages to be processed (events) and callback functions to be executed.

Quene is a first-in, first-out (FIFO) data structure, in which the first events are read first by the main thread. The main thread is read automatically. As soon as the Call Stack is cleared, the first event on Quene is automatically read into the main thread. However, due to the “timer” function, the main thread first checks the execution time, and certain events can only be queued at the specified time, read the event, and execute the corresponding event callback.

Basically, these events are queued in response to external asynchronous events (such as a mouse click or receiving a response to an HTTP request), although if an event does not have a callback, then the event will not be queued in Quene.

I think the key here is to understand what kind of code goes into Quene, which I like to call “asynchronous code “. We all know that JS is a single threaded voice, if both are synchronous and do not support asynchronous, you can imagine how the stack will jam when loading resources. So JS supports asynchronous callbacks. Now, some people might ask why asynchronous code can’t go directly into the Call Stack, but if you think about asynchronous code, it doesn’t make sense to insert it randomly into the Call Stack.

Console.log (1)setTimeout(() => {
  console.log(2)
}, 200)
setTimeout(() => {
  console.log(3)
}, 0)
console.log(4)

// 1 4 3 2 
Copy the code

Browser asynchronous events: DOM events, HTTP requests, setTimeout and other asynchronous events.

Event Loop

The basic job of the event loop is to look at the stack and the task queue, and when the queue sees that the stack is empty, it pushes the first event in the queue to the stack. The callback for the current event is processed before any other messages are processed.

digression

About queues: There are macro-tasks/micro-tasks.

Function execOrder () {setTimeout(() => console.log('timeout'), 0) let promise = new promise ((resolve, reject) => { console.log('Promise') resolve() }) promise .then(() => { console.log('resolved') }) console.log('hi') } // Execution sequence: Promise Hi resolved TimeoutCopy the code