Write at the front – the manual for this article

I’ve been thinking a lot about why asynchrony is so hard to master. There are two answers:

  1. I may not have grasped all the internal structure, but I think I understand it. In fact, I have been operating in the black box, so there is a bug and I don’t know how to do it.
  2. Time. Asynchrony is complicated because it has a time dimension. I struggled to learn asynchrony myself because most of the material was written about this high-latitude process. So I decided to make asynchrony all GIfs, using animation to explain time, hoping to help you understand asynchrony more efficiently.
  • Part1 setTimeout and eventloop
  • Part2 Promise and MiscroTask Queue
  • part3 generator… Yield and async… Await, I am dying while making animation. If you think it is ok, please give me a thumbs up.

Part1 setTimeout works

I. What is asynchronous?

  • Definition of asynchrony

In theory, one person must be able to harvest wheat more slowly than multiple people, such as network request, delegate to another thread, do not occupy the main thread, multiple threads is more powerful.
The main purpose is to be fast. There’s also asynchrony
uncontrolledAsynchrony needs to manage time. Although asynchrony is slow, sequential execution is very reliable, while asynchrony needs to think about how to manage extra threads and when to receive results. What if the thread strikes the next program? That’s the price of being fast.

Ii.settimeout What exactly happened

1) setTimeout construction principle – it is not native JS

Javascript is a single-threaded language. It has only one thread or callback stack. There is no asynchrony in native JS.

In fact:

  1. Asynchrony is a function of JS invoking the Web API provided by the browser.
  2. A structural model of a V8 engine. The following is my simplified version, you need to know what the function of each area is:
  1. Javascript source runtime area,Responsible for storing data and computing data.
  2. The Call Stack and Javascript Source belong to the same V8 engine, and the callback stores the context that the function needs to execute,It mainly manages the running sequence.
  3. The WEB API is provided by Browser and contains many asynchronous functions such as setTimeout timers, Network requests (XHR) and events.

3) Operation principle of setTimeout — Eventloop and Task Queue

This code is very basic, the purpose of the explanation is to clarify how JS works.

  1. JS will initially create a global function, which is not normally present by default. encountersetTimeoutThe functioncbPassed to browser(or Web API), this code blocks (Turn red) Jump executionsayHello
  2. sayHelloAfter execution (Turn green),sayHelloOut of the stack
  3. After 1000ms, Browser puts the functioncbThrow it into the CallStack, executecb(), all execute the defaultglobalAlso out of the stack

3) Introduction of event loop

If setTimeout is 0, who comes first and who comes last? If the answer is not clear, there is still one piece of the puzzle missing to complete the operation of setTimeout.

Let’s take a look at the execution of the code

1. We will start with global being pushed directly. SetTimeout enters browser and continues execution after masking.

2.
sayHelloFunctions are registered in memory(heap) and then executed. But at the moment,
setTimeoutAnd it comes back,
Who should be on the stack first?

Introduced 3.
eventloop, before browser’s function enters the Call Stack
task queueAlso known as the Macro Queue (
Water is blue). Evenloop is a logic,
When the CallStack is empty it pushes the queue function onto the stack. In this case, the stack contains global, cannot be pushed, run first
sayHello("First!" ).

Global () is still there, continue to execute console.log(“second!” ).

4.
Finally, the Call Stack is empty. The callback() function is pushed into the stack.

Part2 Promises waiting for results

I. Operation principle of Promise — “it” will run automatically when conditions are met

This is one of the pieces of the puzzle for understanding async await, so it’s important to understand how promise objects work.

  1. As soon as the promise executes, an Object is returned to place the fetchPromise. And sends browser a request to call the XHR network. That’s the end of the code.
  2. Promise. Then assigns value to the ondepressing attribute of this placeholder object, which will be triggered only when the value has a value. At present, it will not be triggered.
  3. After adding 200s, it returns value: “hi”, which passes back the Promise object and updates value to “hi”, at which point the display function in onFullfill fires.

II. Promise vs. setTimeout — Miscro Task Queue

In the following code, we can see that when executing the setTimeout and promise returns, the first and last problem will occur. In this case, we can introduce the concept of Micro Task Queue to control the order.

  1. After setTimout is executed, it enters the Task Queue, fetchPromise sends an asynchronous request to the network, and the JS part has been executed. Next, blockFor500ms to block the main thread.
  2. If the promise returns after 200ms, the function display is triggered, but the call stack still has functions running. There’s no way to execute so at least let the function have somewhere to wait. We might expect display to be pushed into the Task queue, but in fact display will be pushed into a new queuemicro task queueWait.
  3. task queueandmicro task queueAll followCall stack is pushed when the call stack is emptyThe rules. butmicro task queueDisplay is executed first, and setTimeout is executed last.
"Me first!"
"Hi" //promise
"Hello" //setTimeout
Copy the code

Part3 Async await pull and push

I. How the generator works — the suspension of yield

So here’s the code, and you can guess without looking at the answer, what is the answer?

Element2 = 7!!

The steps are as follows:

  1. Generator createFlow() returns an object with a pointer to Next pointing to createFlow(LinkedList?).
  2. ReturnNextElement. Next () points to createFlow, executes createFlow, and returns yield to newNum assignment.Yield is a very strong instruction, higher than =, and num returns to element1 before newNum completes the assignmentYield also performs another functionThe pause button is pressed for the current execution context
  3. Element2 is executed, and then next(2) passes a value, and then createFlow is calledThe function does not restart the new execution context but continues execution on the original basis, newNum did not complete the assignment, and the value passed in will automatically fill in the assigned variable.newNum=2, yield newNum+5, and follow the same pattern.

II. Async await is just syntactic sugar for generator+ Promise

Let’s start with a bit of async await code

It’s actually the same thing as the code below

Let’s take a look at the order in which asynchrony is added:

1. FutureData yields a promise at yield, and createFlow is paused. The data inside createFlow has not yet been assigned a value.

2. The Promise calls the Web API execution, for example, returns a result “Hi” after 200s. According to the promise mechanism, the result will trigger the execution of doWhenBack, and the doWhenBack will enter the Micro Task Queue for execution.

The event loop waits until the stack is empty and pushes doWhenBack to the stack. The createFlow function is called when the stack is empty. Data is automatically padded with the promise’s return value ‘Hi’, printing out the result.

// Execute result "Me First! "Me second!" "Hi"Copy the code