Elegant asynchronous programming version answer async and await parsing

catalogue

What are aysnc and await

Why async

What does the aysnc function solve

Advantages of async function

How to use async function

async function syntax

await syntax

error handling

Basic structure of async+await

matters needing attention

What are aysnc and await

The async function is the syntax sugar of the Generator function.

Use the Generator function to read two files in turn.

var fs = require('fs');

var readFile = function (fileName){
  return new Promise(function (resolve, reject){
    fs.readFile(fileName, function(error, data){
      if (error) reject(error);
      resolve(data);
    });
  });
};

var gen = function* (){
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

Write the async function as follows.

var asyncReadFile = async function (){
  var f1 = await readFile('/etc/fstab');
  var f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

A comparison shows that the async function is to replace the asterisk (*) of the Generator function with async and the yield with await, that's all.

Why async

In order to make our asynchronous code more like synchronous code

What does the aysnc function solve

Before async/await, we had three ways to write asynchronous code

  1. Nested callback
  2. Promise based chain callback
  3. Using Generators

However, these three methods are not elegant enough. ES7 has made optimization and improvement, and Async/Await came into being. Compared with Async/Await, the nesting of then function of Promise object is cumbersome compared with the execution of Generator (it needs co to be executed automatically, otherwise it has to call next()). Async/Await allows you to easily write synchronous code and has asynchronous mechanism, More concise and clearer logic.

Advantages of async function

The async function improves the Generator function in the following three points.

(1) as like as two peas. The Generator function must be executed by the executor. Therefore, the co function library is built, and the async function has its own executor. That is to say, the execution of the async function is exactly the same as that of the ordinary function.

var result = asyncReadFile();

(2) Better semantics. async and await have clearer semantics than asterisks and yield. async means that there are asynchronous operations in the function, and await means that the following expression needs to wait for the result.

(3) Wider applicability. According to the co function library convention, the yield command can only be followed by the Thunk function or Promise object, while the await command of async function can be followed by Promise object and original type value (numeric value, string and Boolean value, but this is equivalent to synchronous operation).

How to use async function

async function syntax

  • The regular function is automatically converted to Promise, and the return value is also a Promise object
  • The callback function specified by the then method will not be executed until the asynchronous operation inside the async function is completed
  • await can be used internally in asynchronous functions
async function name([param[, param[, ... param]]]) { statements }
name: Function name.
param:  The name of the parameter to pass to the function
statements: Function body statement.
Return value: Returned Promise The object will async function Parse the return value of the function, or reject it with the exception thrown by the function.

await syntax

  • Await is placed before the Promise call. Await forces the following code to wait until the Promise object resolves. The value of resolve is obtained as the operation result of await expression
  • await can only be used inside the async function. If it is used in an ordinary function, an error will be reported
[return_value] = await expression;

expression:  One Promise  Object or any value to wait for.

Return value:return Promise Object. If the waiting is not Promise Object, the value itself is returned.

error handling

In async function, both the data of Promise reject and the logic error will be swallowed silently. Therefore, it is best to put await into try{}catch {}. Catch can catch the data of Promise object rejected or the exception thrown

function timeout(ms) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {reject('error')}, ms);  //reject simulation error, error returned

  });

}

async function asyncPrint(ms) {

  try {

     console.log('start');

     await timeout(ms);  //An error is returned here

     console.log('end');  //So this code will not be executed

  } catch(err) {

     console.log(err); //An error is caught here

  }

}

asyncPrint(1000);

If you don't use try/catch, you can also handle the error as follows (because the async function returns a promise after execution)

function timeout(ms) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {reject('error')}, ms);  //reject simulation error, error returned

  });

}

async function asyncPrint(ms) {

  console.log('start');

  await timeout(ms)

  console.log('end');  //This code will not be executed

}

asyncPrint(1000).catch(err => {

    console.log(err); // Error caught here

});

If you don't want the error to interrupt the execution of the following code, you can intercept and retain the error in advance, as shown below

function timeout(ms) {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

        reject('error')

    }, ms);  //reject simulation error, error returned

  });

}

async function asyncPrint(ms) {

  console.log('start');

  await timeout(ms).catch(err => {  // Be careful to use catch

console.log(err) 

  })

  console.log('end');  //This code will be executed

}

asyncPrint(1000);

Basic structure of async+await

function func(a, b) {
    return a + b
}

let ret = func(10, 30);
let ret1 = func(50, 320);
let ret2 = func(1560, 30);
let ret3 = func(10, 3560);
console.log(ret + ret1 + ret2 + ret3);
If Promise Objects can also be received in a corresponding way, written in a similar way: 
let data1 = await readfilePromise;  // Get successful data directly

The final format of async is as follows:

async function func() {
    let data1 = await promise Object 1;
    let data2 = await promise Object 2;
    let data3 = await promise Object 3;
}
// This is equivalent to having asynchronous function object 1 execute first, then asynchronous function object 2, and then asynchronous function object 3

matters needing attention

  1. If only one basic data type is written after await, it will be wrapped into a Promise object
async function func() {
    let data1 = await 123;
    //1. Only one basic data type is written after await, which will be wrapped into a Promise object
    // That is, data1 is equivalent to: new promise ((resolve, reject) = > {resolve (123)})

    console.log("data1:", data1);   //data1: 123

    return data1
    // return await data1

}

let a = func();

a.then((data)=>{
    console.log(data);  //123 receives the execution result of the Promise object with the above return value
});
  1. If await is followed by a Promise, the value of resolve will be returned
  2. await in async function is asynchronous, not synchronous
async function func() {
    console.log("start-------");
    let data1 = await readFile(filePath1, "utf-8");
    console.log("end-----------");
    let data2 = await readFile(filePath2, "utf-8");
    let data3 = await readFile(filePath3, "utf-8");

    console.log(data1+data2+data3);
}

console.log("start");
func();
console.log("end");

//The output results are as follows:
//start
//start-------
//end
//end-----------

Keywords: Javascript

Added by thomasob on Thu, 30 Dec 2021 14:55:06 +0200