1 the asynchronous

  • “Asynchronous” simply means that a task is divided into two parts, the first part is performed, then the other part is performed, and when you are ready, the second part is performed. For example, if a task is to read a file for processing, the asynchronous execution process is as follows.

This discontinuous execution is called asynchrony. Accordingly, continuous execution is called synchronization.

2 higher order functions

Functions, as first-class citizens, can be used as arguments and return values, or as arguments to functions

2.1 Can be used to generate functions in batches

// Determine if an argument is a string
function isString(param){
	return Object.prototype.toString.call(param) == '[object String]';
}
isString(123);

// Check whether an argument is an array
function isArray(param){
	return Object.prototype.toString.call(param) == '[object Array]';
}
isArray([]);
Copy the code

A function can be a return value

function isType(type){
	return function(param){
  	return Object.prototype.toString.call(param) == `[object ${type}] `; }}let isString = isType('String');
let isArray = isType('Array');
console.log(isString({}))
console.log(isArray([]))

Copy the code

2.2 Can be used for functions that need to be called more than once

A function can be passed as an argument to another function

function eat(){
	console.log("Finished")}// Let him execute several times before executing
function after(times,fn){
  let count = 0;
	return function(){
  	if(count++==times){ fn(); }}}let newEat = after(3,eat);
newEat();
newEat();
newEat();
Copy the code

3. The syntactic goal of asynchronous programming is to make it more like synchronous programming

  • Callback function implementation
  • Event listeners
  • Release subscription
  • Promise/A+ and generator functions
  • async/await

4. The callback

Let’s say I’m going to read a file, asynchronously

let fs = require('fs');
fs.readFile('./1.txt'.'utf8'.function(err,data){
	if(err){ // If err has a value, the program is in error
  	console.log(err);
  }else{ // If err is empty, success with no errors
  	console.log(data); }});Copy the code

The problem with callback functions

  1. Failed to catch an error try catch return
  2. Can’t return
  3. The callback hell
function read(filename){
	fs.readFile(filename,'utf8'.function(err,data){
    if(err){ // If err has a value, the program is in error
      console.log(err);
    }else{ // If err is empty, success with no errors
      console.log(data); }}); }try{
	 read('1.txt');	
}catch(e){
	console.log(e);
}

console.log(2);
Copy the code

When you visit the server, for example, to request an HTML page, such as a list of users. The server reads template files on the one hand, which can be EJS, PUG, JADE, handlebar, and data on the other (which can be placed in files or data), both of which are very slow, so they are asynchronous.

  • This is an ugly way to write it
  • Very difficult to maintain
  • It’s inefficient because it’s serial
fs.readFile('./template.txt'.'utf8'.function(err,template){
  fs.readFile('./data.txt'.'utf8'.function(err,data){
    console.log(template+' '+data); })})Copy the code

How to solve this problem of nested callback

6. Asynchronous process solutions

6.1 Through event publishing subscription

// This is a class in the Node core module, through which you can pass an instance of the time emitter, which has two core methods
// On emit,on means to register listener, and emit means to emit event
let EventEmitter = require('events');
let eve = new EventEmitter();
// This HTML object is stored
let html = {}; // template data

// Listen for a data acquisition success event and call the callback function when the event occurs
eve.on('ready'.function(key,value){
	html[key] = value;
  if(Object.key(html).lenght==2) {console.log(html);
  }
})

fs.readFile('./template.txt'.'utf8'.function(err,template){
  // the event name 2 argument is passed to the callback function
	eve.emit('ready'.'template',template);
})

fs.readFile('./data.txt'.'utf8'.function(err,data){
  // 
	eve.emit('ready'.'data',data);
})
Copy the code

6.2 Sentry Variables

// Use a sentinel to solve the problem
let html = {}
function done(key,value){
	html[key]=value;
  if(Object.keys(html).length===2) {console.log(html); }}; fs.readFile('./template.txt'.'utf8'.function(err,template){
	done("template",data)
})

fs.readFile('./data.txt'.'utf8'.function(err,data){
	done("data",data)
})
Copy the code
// Use a sentinel to solve the problem
let html = {}

function render(lenght,cb){
	let html = {};
  if(Object.keys(html).length===lenght){ cb(html); }}let done = render(2.function(html){
	console.log(html);
});

fs.readFile('./template.txt'.'utf8'.function(err,template){
	done("template",data)
})

fs.readFile('./data.txt'.'utf8'.function(err,data){
	done("data",data)
})
Copy the code

6.4 Generator Generators/ yield

A generator is a function that you can use to generate iterators. A generator function is different from a normal function, where once you call a generator function, it will always run out of time but a generator function can run in between, it can run in between

The yield defines the value returned from the generator function via the iterator protocol. If omitted, undefined is returned.

function *go(params) {
        console.log(1);
        // where b is to provide external input
        // This line implements input and output, with output placed after yield and input before yield
        let b = yield 'a';
        console.log(2);
        let c = yield b;
        console.log(3);
        return c;
    }
// Generator functions are different from normal functions in that when called, the function is not executed immediately
// It returns the generator's iterator, which is an object that returns a value object every time next is called
let it = go();;
let r1 = it.next();
// The first call to next returns an object with two properties, value for yield and done for iteration completion
console.log(r1); //{value:'a',done:false};
// Next does not need to pass parameters for the first time
let r2 = it.next('B values');// Pass to b
console.log(r2); // {value:'a',done:false};
let r3 = it.next();// {value:undefined,done:true};
console.log(r3);
Copy the code

6.5 Promise to handle

A Promise object is a proxy object (proxy for a value), and the proxied value may not be known at the time the Promise object is created. It allows you to bind handlers for success and failure of asynchronous operations.

6.5.1 example
let p1 = new Promise((resolve, reject) = > {
     setTimeout((a)= > {
         resolve(1000)},1000);
});

p1.then(res= >{
	console.log(res)
})
Copy the code

Tactical fix packs for 6.5.2 promise. All

It receives an array of promises, and if the promise completes all of these, the promise succeeds, and if one fails, the whole thing fails

When multiple data requests are made asynchronously, all is used

let p1 = new Promise((resolve, reject) = > {
     setTimeout((a)= > {
         resolve(1000)},1000);
});

let p2 = new Promise((resolve, reject) = > {
     setTimeout((a)= > {
         resolve(1000)},1000);
});

Promise.all([p1,p2]).then(res= >{
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
    console.log(res);
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
},err=>{
 		console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
    console.log(err);
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
})
Copy the code

The principle of

function gen(times,cb) {
    let result = [],count=0
    return function(i,data){
        result[i] = data;
        if(++count == times) { cb(result); }}}Promise.alls = function (promises) {
    return new Promise(function (resovle, reject) {
        let result = []
        let count =0
        let done = gen(promises.length,resovle)
        // function done(i,data){
        // result[i] = data;
        // if (++count== promises.length) {
        // resovle(result)
        / /}
        // }
        for (let i = 0; i < promises.length; i++) {
        // promises[i].then(done.bind(null,i));
             promises[i].then(function (data) { done(i,data) }, reject); }})}Promise.alls([p1,p2]).then(res= >{
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
    console.log(res);
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
},error=>{
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
    console.log(error);
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
})
Copy the code

6.5.3 promise. Race

You receive an array of promises, and if you get one success, you’re successful, and if you get one failure, you’re failed

When you have three unstable ports, but you can request all three ports at the same time, the one who comes back first uses the one

let p1 = new Promise((resolve, reject) = > {
     setTimeout((a)= > {
         resolve(1000)},1000);
});

let p2 = new Promise((resolve, reject) = > {
     setTimeout((a)= > {
         resolve(1000)},1000);
});

Promise.race([p1,p2]).then(res= >{
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
    console.log(res);
    console.log('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =');
})
Copy the code

The principle of

Promise.race = function (promises) {
    return new Promise(function (resovle, reject) {
        for (let i = 0; i < promises.length; i++) { promises[i].then(resovle, reject); }})}Copy the code

6.6 Co

Co is a generator-based flow control tool for Node.js and browsers. With Promise, you can write non-blocking code in a more elegant way.

let fs = require('fs');
function readFile(filename) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filename, function (err, data) {
      if (err)
        reject(err);
      elseresolve(data); })})}function *read() {
  let template = yield readFile('./template.txt');
  let data = yield readFile('./data.txt');
  return template + '+' + data;
}
co(read).then(function (data) {
  console.log(data);
}, function (err) {
  console.log(err);
});
Copy the code
function co(gen) {
  let it = gen();
  return new Promise(function (resolve, reject) {!function next(lastVal) {
      let {value, done} = it.next(lastVal);
      if (done) {
        resolve(value);
      } else {
        value.then(next, reason => reject(reason));
      }
    }();
  });
}
Copy the code

6.7 Async/await

With the async keyword, you can easily do what you used to do with generators and co functions but it’s really just the generator+ Promise syntax

The advantages of Async

  • Built-in actuator
  • Better semantics
  • Wider applicability
async function timeout() {
   return 'hello world'
}

timeout().then(res= >{
  console.log(res);
})
console.log('I'll do it later, but I'll do it first.');
Copy the code

Async returns a promise

Let me give you an example

function loading(num) {
    return new Promise((resolve, reject) = > {
        setTimeout((a)= > {
            resolve(2 * num)
        }, 2000); })}// This is a function constructor
Copy the code

I want to pass in three values 30, 50, and 40 and sum them up. The delay time simulates the network request time

async function testResult() {
  let one = await loading(30);
  let two = await loading(50);
  let three = await loading(40);
  console.log(one + two + three);
}

testResult();
Copy the code