The Event Loop mechanism
Instead of waiting for an asynchronous task to return, the JS engine hands it off to another module in the browser (webCore, in the case of WebKit) and continues to perform other tasks in the call stack. When an asynchronous task returns a result, the JS engine adds the task to a different queue from the current call stack, called the event queue.
Task queues and event loops
In JavaScript runtime, in addition to a running main thread, the engine also provides a task queue of various asynchronous tasks that need to be handled by the current program. (In fact, there are multiple task queues depending on the type of asynchronous task. For ease of understanding, assume that there is only one queue.
First, the main thread performs all synchronization tasks. When all the synchronous tasks are completed, the asynchronous tasks in the task queue are viewed. If the condition is met, the asynchronous task is re-entered into the main thread to begin execution, and it becomes a synchronous task. The next asynchronous task enters the main thread to start execution. Once the task queue is empty, the program ends execution.
Asynchronous tasks are usually written as callback functions. Once the asynchronous task re-enters the main thread, the corresponding callback function is executed. If an asynchronous task does not have a callback function, it will not enter the task queue, that is, it will not re-enter the main thread, because there is no callback function to specify the next operation.
How does a JavaScript engine know if an asynchronous task has a result, if it can get into the main thread? The answer is that the engine is constantly checking, over and over again, to see if pending asynchronous tasks are ready to enter the main thread once the synchronous task has finished. This Loop checking mechanism is called an Event Loop. Wikipedia defines it as: An event loop is a programming construct that waits for and dispatches events or messages in a program.
Macro-task, micro-task
Macro task: overall code script, setTimeout, setInterval… Micro-task: Promises, Object.observe…
Macro tasks: Host-initiated tasks are macro tasks, such as setTimeout, setInterval, and setImmediate. I/O Micro tasks: JavaScript engine initiates micro tasks, such as Promise
The JavaScript engine waits for the host environment to assign macro tasks, and the queue of macro tasks can be thought of as an event loop
Asynchronous operations
Synchronous and Asynchronous Tasks
All tasks in the program can be categorized into two categories: synchronous and asynchronous.
Synchronous tasks are those that are not suspended by the engine and are queued for execution on the main thread. You can perform the next task only after the previous task is completed.
Asynchronous tasks are those that are put aside by the engine, not into the main thread, but into the task queue. An asynchronous task (in the form of a callback function) is executed on the main thread only if the engine considers it ready to execute (such as an Ajax operation that results from the server). The code after the asynchronous task runs immediately without waiting for the asynchronous task to finish, which means that the asynchronous task has no “blocking” effect.
For example, Ajax operations can be handled as synchronous or asynchronous tasks, at the developer’s discretion. In the case of a synchronous task, the main thread waits for the Ajax operation to return the result and then executes. In the case of asynchronous tasks, the main thread makes an Ajax request and then executes the corresponding callback function after the Ajax operation results.
Asynchronous mode of operation
The callback function
function f1(callback) {
// ...
callback();
}
function f2() {
// ...
}
f1(f2);
Copy the code
Event listeners
function f1() {
setTimeout(function () {
// ...
f1.trigger('done');
}, 1000);
}
f1.on('done', f2);
Copy the code
Publish/subscribe
function f1() {
setTimeout(function () {
// ...
jQuery.publish('done');
}, 1000);
}
jQuery.unsubscribe('done', f2);
Copy the code
Promise
function move(ele, target, dir) {
return new Promise(resolve= > {
function fn() {
let startLeft = parseInt(getComputedStyle(ele, null)[dir]);
// console.log(startLeft)
// let speed =(target-startLeft)/ Math.abs( target-startLeft ) ;
let speed = (target - startLeft) > 0 ? 1 : -1;
setTimeout(() = > {
startLeft += speed;
if (startLeft === target) {
// console.log(" Movement completed ");
// cb && cb();
resolve("Motion completed");
} else {
ele.style[dir] = startLeft + "px"; fn(); }},10); } fn(); })}Copy the code
Async and await
void async function asyncmove(){
await move(ele, 300."left");
await move(ele, 300."top");
await move(ele, 0."left");
await move(ele, 0."top"); } ()Copy the code
Generator, iterator
function*fn(){
yield new Promise((resolve,reject) = >{
setTimeout(() = >{
console.log("a");
resolve(1);
},500);
});
yield new Promise((resolve,reject) = >{
setTimeout(() = >{
console.log("b");
resolve(2);
},500);
});
yield new Promise((resolve,reject) = >{
setTimeout(() = >{
console.log("c");
resolve(3);
},500);
});
}
co(fn);
function co(fn){
let f = fn();
next();
function next(data){
let result = f.next();
if(! result.done){// Execute the next async after the last async completes
result.value.then((info) = >{
console.log(info,data); next(info); }); }}}Copy the code
The resources
The Event Loop is used to execute JavaScript. “Tasks, MicroTasks, How JavaScript works: Event loops and the rise of Asynchronous programming + 5 ways to code better with Async /await! The Event Loop mechanism in JavaScript is microtask, macro task, synchronous, asynchronous, Promise, Async, await XXXX