preface

Async is simply a syntactic sugar for Generator, and you can look at Generator functions in the previous article before reading this article. Understanding Generator makes it easy to understand why Async is the perfect solution for asynchronous programming.

directory

  • Async function
  • Principle of Async function
  • Common aboutasyncThe pen test

Async function

const fs = require('fs');

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

const foo = function* () {
  const f1 = yield readFile('/src/lib');
  const f2 = yield readFile('/src/utils');

  console.log(f1.toString());
  console.log(f2.toString());
};
Copy the code

Write Generator foo as async, like this:

  const asyncReadFile = async function () {
  const f1 =  await readFile('/src/lib');
  const f2 =  await readFile('/src/utils');

  console.log(f1.toString());
  console.log(f2.toString());
};
Copy the code

As you can see, the async function simply replaces the asterisk (*) of the Generator function with async, replaces yield with await, and nothing more.

The Async function is a generator-based improvement, as shown in the following four points

  1. Built-in actuators.GeneratorA function must be executed by an executor. That’s where it comes inThunkFunctions andcoModule, andasyncFunctions come with their own actuators.asyncFunctions are executed just like normal functions.
asyncReadFile();
Copy the code
  1. Better semantics. Async and await are semantic clearer than asterisks and yield. Async means that there is an asynchronous operation in a function, and await means that the following expression needs to wait for the result.

  2. Wider adaptability. Even though Generator functions can be executed automatically with the help of the CO module, the CO module can only be followed by Thunk functions or Promise objects, while async functions can be followed by await commands with Promise objects and primitive values (numeric, string, and Boolean values, etc.). But this is automatically switched to immediate Resolved Promise)

  3. The return value is Promise. Aysnc returns a Promise, which is much more convenient than Generator returns an Iterator.

Async functions can be thought of as multiple asynchronous operations wrapped as a Promise object, and await commands are syntactic sugar for internal THEN commands.

In short, the Generator function is a coroutine that JS learns from other languages and implements according to the single-thread characteristics of JS, but it is much more troublesome to use. Each time, it has to write its own executor, while async function is born to solve these repetitive tasks. The async function encapsulates the Generaor function and the autoexecutor perfectly.

The implementation principle of async function

This is to wrap the Generator function and the auto-executor in one function.

async function fn(args) {
    // ...
}
function fn(args) {
    return spawn(function* () {
        // ...})}Copy the code

All async functions can be written in the second form above, where the spawn function is the auto-executor.

// Accept a Generator as an argument and return a Promise object
function spawn(genF) {
  return new Promise(function(resolve, reject) {
    // Execute genF to get an internal pointer object
    const gen = genF();

    function step(nextF) {
      let next;

      // Perform error handling
      try {
        next = nextF();
      } catch(e) {
        return reject(e);
      }
      if(next.done) {
        return resolve(next.value);
      }

      // Convert next. Value to a Promise object
      Promise.resolve(next.value).then(function(v) {
        step(function() { return gen.next(v); });
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }

    // call step repeatedly
    step(function() { return gen.next(undefined); });

  });
}
Copy the code

As you can see, this is a combination of a Generator function and a Promise that implements an automatic executor that returns a Promise object

Common aboutasyncThe pen test

  • To implement asleep:
  • Implement a traffic light: red 2 seconds, yellow 1 seconds, green 3 seconds
  • useasyncimplementationPromise.all()The effect of

Implement a sleep

Output 1, 2, 3, 4, 5 at 1 second intervals

function sleep(interval) {
    return new Promise(resolve= >{ setTimeout(resolve, interval); })}/ / usage
async function one2FiveInAsync() {
    for (let i = 1; i <= 5; i++) {
        console.log(i);
        await sleep(1000);
    }
}
one2FiveInAsync();

Copy the code

Implement a traffic light

Red 2 seconds, yellow 1 second, green 3 seconds

function sleep(duration) {
    return new Promise(resolve= >{ setTimeout(resolve, duration); })}async function changeColor(color, duration) {
    console.log('Current color', color);
    await sleep(duration);
}
async function main() {
    await changeColor('red'.2000);
    await changeColor('yellow'.1000);
    await changeColor('green'.3000);
}
main();
Copy the code

Use async to implement promise.all ()

Assume that getFoo and getBar are two functions that make ajax requests.

/ / write one
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

/ / write two
let fooPromise = getFoo();
let barPromise = getBar();

let foo = await fooPromise;
let bar = await barPromise;
Copy the code

Both methods, getFoo and getBar, fire at the same time, thus shortening the execution time of the program.

This is just a simple example. Think about it and write the full code.

conclusion

  • asyncThe principle of the function isGeneratorFunctions and autoactuators are wrapped up.
  • GeneratorThat is, you can temporarily execute and pick up where you left off. For example, an interface request is sent, after which JS can do something else, and when the interface request comes back (the data comes in through Next), execution continues. But it doesn’t work automatically, so you need an autoexecutor,thunkFunctions andcoModules are both, but Async gives us a better encapsulation.

about

This article started on my Github blog

Recently, WE launched a 100-day front-end advanced plan, which is mainly to dig into the principle behind each knowledge point. Welcome to follow the wechat public account “Mucode star”, and we will study together and punch the clock for 100 days.