Principle of this paper:
JavaScript is single-threaded, and setTimeout puts code at the end of the thread.
Promises are established and executed in the same order as normal code.
A Promise does not trigger a subsequent THEN until the state changes to resolve
- It will take about 15-25 minutes to finish this article
- Pre-knowledge of this article: basic JS, Promise objects, ES6 and other basic knowledge
- Reading Difficulty: Elementary
- All the code and output of this article are written out, so you can browse the article without using a compiler
If you know the results of the following code, this article is of limited benefit to you
const showNode = document.getElementById("show");
showNode.innerHTML += "normal | ";
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
setTimeout((a)= > { resolve("then |"); }, 0)
})
promise.then((res) = > {
setTimeout((a)= > { showNode.innerHTML += 'then wait | ' }, 0)
showNode.innerHTML += res;
return " next then | ";
}).then((res) = > {
showNode.innerHTML += res;
return " next next then | ";
}).then((res) = > {
showNode.innerHTML += res;
})
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0)
/ / output: normal | promise | then | next then | next next then | wait |
// then wait |
Copy the code
The text start
Javascript engine single thread mechanism
-
To be clear, JavaScript engines are single-threaded
-
JavaScript is single-threaded and cannot execute multiple pieces of code simultaneously. While a piece of code is executing, all subsequent tasks must wait, forming a task queue. Fetching the next task from the queue once the current task has finished is often called “blocking execution.”
-
Asynchronous code is executed only if there is no synchronous code to execute in the JS thread
The js thread knowledge can be moved to the JS single thread and setTimeout execution principle
The execution flow of promise,then and setTimeout
Execute the normal order -> then -> setTimeouts -> THEN setTimeouts
Note 1: showNode is the element I used to get the HTML and display it directly on the page, replacing console.log
Note 2: For example code, new code or modified code, corresponding comments will be added at the end of the code
Normal execution: The command is executed from top to bottom
Environment 1 plain code comes before promise
showNode.innerHTML += "normal | ";
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
})
/ / output: normal | promise |
Copy the code
Environment 2 Promises before normal code
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
})
showNode.innerHTML += "normal | ";
/ / output: promise | normal |
Copy the code
- Promises are executed immediately after they are made, from top to bottom in the normal code execution order
And then: After the normal execution is complete, then is executed
Environment 3 adds then
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
resolve("then |") // Add new code
})
promise.then((res) = > { // Add new code
showNode.innerHTML += res; // Add new code
}) // Add new code
showNode.innerHTML += "normal | "; // Code location changes
/ / output: promise | normal | then |
Copy the code
- When the state of the promise is changedpendingintofulfilledAfter, corresponding to usethenWill be executed.
- Normally executed code is executed in the first batch, then in the second batch, and then when the first batch is complete
External setTimeout: executes after then
Environment 4 added a setTimeout to the global
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0) // Add new code
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
resolve("then |")
})
promise.then((res) = > {
showNode.innerHTML += res;
})
showNode.innerHTML += "normal | ";
/ / output: promise | normal | then | wait |
Copy the code
- SetTimeout pushes code execution to the end of the thread, in the third batch
Environment 5 more then
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
resolve("then |")
})
promise.then((res) = > {
showNode.innerHTML += res;
return " next then | "; // Add new code
}).then((res) = > { // Add new code
showNode.innerHTML += res; // Add new code
return " next next then | "; // Add new code
}).then((res) = > { // Add new code
showNode.innerHTML += res; // Add new code
})
showNode.innerHTML += "normal | ";
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0)
/ / output: promise | normal | then | next then | next next then | wait |
Copy the code
- As mentioned earlier, the normal sequence of code execution is in the first batch, then in the second batch, setTimeout in the third batch,
- Execute the second batch after the completion of the first batch, execute the third batch after the completion of the second batch
In the promiseSetTimeout: After using setTimeout, all are carried to the end of the process and printed in the normal code order
Environment 6 Include setTimeout in the promise
let promise = new Promise((resolve, reject) = > {
// Add new code
setTimeout((a)= > { showNode.innerHTML += "promise wait | "; }, 0)
showNode.innerHTML += "promise | ";
resolve("then |")
})
promise.then((res) = > {
showNode.innerHTML += res;
return " next then | ";
}).then((res) = > {
showNode.innerHTML += res;
return " next next then | ";
}).then((res) = > {
showNode.innerHTML += res;
})
showNode.innerHTML += "normal | ";
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0)
/ / output: promise | normal | then | next then | next next then |
// promise wait | wait |
Copy the code
- Because the Promise was in the first batch, the setTimeout set in the Promise was referred to in the third batch
- In the third batch, the process is also executed from top to bottom
Environment 7 External setTimeout precedes setTimeout in the Promise
showNode.innerHTML += "normal | ";
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0) // Code location changes
let promise = new Promise((resolve, reject) = > {
setTimeout((a)= > { showNode.innerHTML += "promise wait | "; }, 0)
showNode.innerHTML += "promise | ";
resolve("then |")
})
promise.then((res) = > {
showNode.innerHTML += res;
return " next then | ";
}).then((res) = > {
showNode.innerHTML += res;
return " next next then | ";
}).then((res) = > {
showNode.innerHTML += res;
})
/ / output: normal | promise | then | next then | next next then | wait |
// promise wait |
Copy the code
Environment 8 promose wraps Resolve with setTimeout
showNode.innerHTML += "normal | ";
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0)
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
setTimeout((a)= > { resolve("then |"); }, 0) // Code changes
})
promise.then((res) = > {
showNode.innerHTML += res;
return " next then | ";
}).then((res) = > {
showNode.innerHTML += res;
return " next next then | ";
}).then((res) = > {
showNode.innerHTML += res;
})
/ / output: normal | promise | wait | then | next then | next next then |
Copy the code
- Again, think in terms of batches, setTimeout is set in the first batch, and the function executed in it is referred to in the third batch.
- Promise only state changesfulfilledBefore it triggers the correspondingthen
- Will control the state in the first batch
resolve()
To mention the third batch is to change the original second batchthen
All the implementation is referred to the third instalment. - The first is code executed in normal order, the second is empty, and the third is executed from top to bottom.
Environment 9 moves the setTimeout outside the Promise down
showNode.innerHTML += "normal | ";
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
setTimeout((a)= > { resolve("then |"); }, 0)
})
promise.then((res) = > {
showNode.innerHTML += res;
return " next then | ";
}).then((res) = > {
showNode.innerHTML += res;
return " next next then | ";
}).then((res) = > {
showNode.innerHTML += res;
})
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0) // Code location changes
/ / output: normal | promise | then | next then | next next then | wait |
Copy the code
SetTimeout in environment 10 then
showNode.innerHTML += "normal | ";
let promise = new Promise((resolve, reject) = > {
showNode.innerHTML += "promise | ";
setTimeout((a)= > { resolve("then |"); }, 0)
})
promise.then((res) = > {
// Add new code
setTimeout((a)= > { showNode.innerHTML += 'then wait | ' }, 0)
showNode.innerHTML += res;
return " next then | ";
}).then((res) = > {
showNode.innerHTML += res;
return " next next then | ";
}).then((res) = > {
showNode.innerHTML += res;
})
setTimeout((a)= > { showNode.innerHTML += "wait | " }, 0)
/ / output: normal | promise | then | next then | next next then | wait |
// then wait |
Copy the code
- First batch: Execute code in normal order.
- Second batch: empty
- Third batch: the end of the thread mentioned by setTimeout
- Batch 4: referred to the end of the thread by setTimeout in then
This is the end of the article
This article according to their own understanding, according to the idea of “batch” to explain, hoping to make the article appears more easy to understand.
If there is something wrong, please point it out in the comments section or send me a private message.
Your advice will make my next article more exciting