JS asynchronous execution mechanism

What is asynchronous execution

In order to improve the running efficiency of Javascript code, JS adopts asynchronous call mechanism (such as Ajax operation) for some function methods. Asynchronously executed function methods are executed independently of each other and simultaneously, rather than in a queue, to avoid blocking code execution and reduce unnecessary waiting time.

Let’s take a chestnut

Most novice programmers will follow a linear thinking approach to code design, which conflicts with the asynchronous execution mechanism in JS.

For example, in Node, we want to assign a string from a file to a variable after reading the document stream, and then use the console.log() method to output the contents of the file. If we were to design our code in a linear way, we would write the following operation:

// Requirements: encapsulate a method, pass in a path, can read the corresponding file
const fs = require('fs');
const path = require('path');

// Given the file path, returns what was read
function getFileByPath(fpath) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else {
      varstr = dataStr; }})}// Call the read file method
getFileByPath(path.join(__dirname, './files/1.txt'));

console.log(str);
Copy the code

The console output is

ReferenceError: str is not defined

This is because we tend to think in a linear way that STR is defined and assigned before console.log(). In reality, however, JS can perform basic operations like console.log() and for loops instantaneously after being parsed. Are executed in queues, such as:

var test = function () {
  console.log('1');
}
test(a);for (var i = 2; i < 5; i++) {
  console.log(i);
}

console.log('6');
Copy the code

The console output is

One, two, three, four, five, six

However, reading a file is an operation that blocks code, so JS puts it on an asynchronous queue and executes the back code, so the correct order of code execution in chestnut is console.log() followed by getFileByPath().

The callback function

So what if we just need to have a step after the file is read, rather than skip the file and execute it directly?

This is where the idea of “callback functions” comes to the rescue. Most people are familiar with how callback functions are used in jQuery, but few people are new to jQuery.

What if, instead of using the callback function, we use the primitive method of executing some operations after reading a file? That’s just rewriting the whole getFileByPath() method:

Const fs = require(const fs = require() const fs = require()'fs');
const path = require('path'); // Given the file path, returns what was readfunction getFileByPath(fpath) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else{ var str = dataStr; + console.log(str); } // call getFileByPath(path.join(__dirname,'./files/1.txt'));
Copy the code

This way we can print the read file content in the console after the getFileByPath method is straight through. However, such an operation is not a good solution to our problem. If the method is encapsulated and used by others, others need to change the source code to achieve the function method, which is obviously not flexible, and even change the original function of the method.

So we need to set up a callback function, after the asynchronous operation is complete, we need to do the next operation.

To understand how callback functions work, let’s break down the changed code:

if (err)
      throw err;
    else {
      var str = dataStr;
+     console.log(str);
    }
Copy the code

If var STR = dataStr; if var STR = dataStr; Console.log (STR) is wrapped in a method named CLG, so we can do the same thing by executing CLG () after else:

function getFileByPath(fpath) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else{ clg(dataStr); }})}function clg(dataStr){
	var str = dataStr;
	console.log(str);
}

getFileByPath(path.join(__dirname, './files/1.txt'));
Copy the code

This would allow us to put whatever we do after reading the file into a CLG method, which would actually be called a callback, but it would still make the code cumbersome.

Let’s take a look at jQuery’s callback functions:

$(‘#demo’).animate({“opacity”:”1″}, 1000, fucntion(){… The callback function.. });

JQuery passes the callback function as a parameter to the method, so we just append a parameter to the getFileByPath() method, which is a function, and we can execute the function after the else in the source code. This function is called the “callback function”.

The overwritten getFileByPath() method

function getFileByPath(fpath, callback) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else{ callback(dataStr); }})}Copy the code

Then when we call, we write a method function in the argument bit, and that method gets passed inside the getFileByPath() method, waiting for the file to be read before going straight.

getFileByPath(path.join(__dirname, './files/1.txt'), function(dataStr){
	var str = dataStr;
	console.log(str);
});
Copy the code

It is worth noting that when we set the parameter bits passed in the source code, we set an argument to the callback function

callback(dataStr);

The dataStr is the contents of the file read by the file read operation, and we pass a variable into the callback() method, which can be called in the callback function written when we call getFileByPath().

– ̗̀(ᵔ⌔ᵔ๑)

JS asynchronous execution mechanism

What is asynchronous execution

In order to improve the running efficiency of Javascript code, JS adopts asynchronous call mechanism (such as Ajax operation) for some function methods. Asynchronously executed function methods are executed independently of each other and simultaneously, rather than in a queue, to avoid blocking code execution and reduce unnecessary waiting time.

Let’s take a chestnut

Most novice programmers will follow a linear thinking approach to code design, which conflicts with the asynchronous execution mechanism in JS.

For example, in Node, we want to assign a string from a file to a variable after reading the document stream, and then use the console.log() method to output the contents of the file. If we were to design our code in a linear way, we would write the following operation:

// Requirements: encapsulate a method, pass in a path, can read the corresponding file
const fs = require('fs');
const path = require('path');

// Given the file path, returns what was read
function getFileByPath(fpath) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else {
      varstr = dataStr; }})}// Call the read file method
getFileByPath(path.join(__dirname, './files/1.txt'));

console.log(str);
Copy the code

The console output is

ReferenceError: str is not defined

This is because we tend to think in a linear way that STR is defined and assigned before console.log(). In reality, however, JS can perform basic operations like console.log() and for loops instantaneously after being parsed. Are executed in queues, such as:

var test = function () {
  console.log('1');
}
test(a);for (var i = 2; i < 5; i++) {
  console.log(i);
}

console.log('6');
Copy the code

The console output is

One, two, three, four, five, six

However, reading a file is an operation that blocks code, so JS puts it on an asynchronous queue and executes the back code, so the correct order of code execution in chestnut is console.log() followed by getFileByPath().

The callback function

So what if we just need to have a step after the file is read, rather than skip the file and execute it directly?

This is where the idea of “callback functions” comes to the rescue. Most people are familiar with how callback functions are used in jQuery, but few people are new to jQuery.

What if, instead of using the callback function, we use the primitive method of executing some operations after reading a file? That’s just rewriting the whole getFileByPath() method:

Const fs = require(const fs = require() const fs = require()'fs');
const path = require('path'); // Given the file path, returns what was readfunction getFileByPath(fpath) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else{ var str = dataStr; + console.log(str); } // call getFileByPath(path.join(__dirname,'./files/1.txt'));
Copy the code

This way we can print the read file content in the console after the getFileByPath method is straight through. However, such an operation is not a good solution to our problem. If the method is encapsulated and used by others, others need to change the source code to achieve the function method, which is obviously not flexible, and even change the original function of the method.

So we need to set up a callback function, after the asynchronous operation is complete, we need to do the next operation.

To understand how callback functions work, let’s break down the changed code:

if (err)
      throw err;
    else {
      var str = dataStr;
+     console.log(str);
    }
Copy the code

If var STR = dataStr; if var STR = dataStr; Console.log (STR) is wrapped in a method named CLG, so we can do the same thing by executing CLG () after else:

function getFileByPath(fpath) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else{ clg(dataStr); }})}function clg(dataStr){
	var str = dataStr;
	console.log(str);
}

getFileByPath(path.join(__dirname, './files/1.txt'));
Copy the code

This would allow us to put whatever we do after reading the file into a CLG method, which would actually be called a callback, but it would still make the code cumbersome.

Let’s take a look at jQuery’s callback functions:

$(‘#demo’).animate({“opacity”:”1″}, 1000, fucntion(){… The callback function.. });

JQuery passes the callback function as a parameter to the method, so we just append a parameter to the getFileByPath() method, which is a function, and we can execute the function after the else in the source code. This function is called the “callback function”.

The overwritten getFileByPath() method

function getFileByPath(fpath, callback) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err)
      throw err;
    else{ callback(dataStr); }})}Copy the code

Then when we call, we write a method function in the argument bit, and that method gets passed inside the getFileByPath() method, waiting for the file to be read before going straight.

getFileByPath(path.join(__dirname, './files/1.txt'), function(dataStr){
	var str = dataStr;
	console.log(str);
});
Copy the code

It is worth noting that when we set the parameter bits passed in the source code, we set an argument to the callback function

callback(dataStr);

The dataStr is the contents of the file read by the file read operation, and we pass a variable into the callback() method, which can be called in the callback function written when we call getFileByPath().

– ̗̀(ᵔ⌔ᵔ๑)