This is the 8th day of my participation in Gwen Challenge

1. Callback function

A callback is a function that is passed as an argument to another function and then executed after that function has finished executing. Suppose there are two functions f1 and f2, f2 waits for the result of f1, f1()–>f2(); If f1 is time-consuming, we can rewrite f1 and write f2 (the arrow function) as the f1 callback:

function f1(callback){
  setTimeout(() = > {
    let name = 'Ming'
    console.log('Hello.') // the task code for f1
    callback(name)
  }, 100);
}
f1((name) = >{
	console.log('I am'+name)
})
/ / hello, everyone
// I am Xiao Ming
Copy the code

Advantages: simple, convenient and practical. Cons: Easy to form callback function hell. If we only have one asynchronous operation, there is no problem with using the callback function to handle it. However, if we were to nest many callbacks, we would have a big problem, because the multiple asynchronous operations would be strongly coupled and the code would be messy and unmanageable. This situation is called “callback hell.”

getData('XXX1'.() = > {
  // Callback function body
  getData('XXX2'.() = > {
    // Callback function body
    getData('XXX3'.() = > {
      // Callback function body
      getData('XXX4'.() = > {
        // Callback function body
        getData('XXX5'.() = > {
          // Callback function body})})})})})Copy the code

2. Promise objects

Promise is a solution to asynchronous programming with the following advantages: Promise is chained programming, effectively solve the headache of the callback hell problem, the result of Promise has two states of success and failure, only the result of asynchronous operation, can determine which state is currently, any outside operation can not change this state. 2.1 Common apis Resolve Returns the result of an asynchronous operation. Reject Returns the result of an asynchronous operation. Then An operation in the Promise state is successful Action performed regardless of whether the Promise state succeeds or fails

//ES6 specifies that a Promise object is a constructor that generates a Promise instance.
    const p = new Promise(function(resolve,reject){
        if(success){
            resolve('Successful outcome')}else{
            reject('Result of failure')
        }
    })
    p.then(function (res) {
        // What do I do to receive data from resolve

    },function (err) {
        // Accept data, do something
    })
    p.catch(function (err) {
        What do I do when I receive data in reject or catch an error from a run in THEN ()
    })
    p.finally(function(){
        // Execute regardless of state
    })
Copy the code
const p = new Promise((resolve, reject) = >{
  setTimeout(() = > {
    let name = 'Ming'
    resolve(name)
  }, 100);
});
p.then((res) = > {
  console.log(res)
})
Copy the code

2.2 Promise.all Promise.all method is used to wrap multiple Promise instances into a new Promise instance. Const p = promise. all([p1, p2, p3]) the state of p is determined by p1, p2 and p3, which can be divided into two cases. (1) Only when the states of P1, P2 and P3 become depressing, the state of P will become depressing. At this time, the return values of P1, P2 and P3 will form an array and be passed to the callback function of P. (2) As long as p1, P2 and P3 are rejected, P becomes rejected, and the return value of the first rejected instance is passed to p’s callback function.

let p1 = new Promise((resolve, reject) = > {
  console.log('begin p1');
  setTimeout(() = > {
    console.log('end p1');
    resolve('p1');
  }, 2);
});
p1.then(() = > {
  console.log('then p1');
})

let p2 = new Promise((resolve, reject) = > {
  console.log('begin p2');
  setTimeout(() = > {
    console.log('end p2');
    resolve('p2');
  },3);
})
p2.then(() = > {
  console.log('then p2');
})

setTimeout(() = > {
  console.log('setTimeout: p3');
  let p3 = Promise.all([p1, p2]).then((datas) = > {
    console.log('begin p3');
    console.log('end p3');
  });
  p3.then(() = > {
    console.log('then p3');
  });
},1);
console.log('mark p4');

// begin p1
// begin p2
// mark p4
// setTimeout: p3
// end p1
// then p1
// end p2
// then p2
// begin p3
// end p3
// then p3
Copy the code

3. Event monitoring

In event-driven mode, tasks are executed not by code order, but by whether an event occurs. F1. on(‘done’,f2); on(‘done’,f2); That is, when a done event occurs in f1, f2 is executed.

function f1(){
  settimeout(function(){
    // the task code for f1
    f1.trigger('done');  // Immediately after the execution is complete, the done event is triggered to start the f2 execution
  },1000);
}
Copy the code

Advantages: easy to understand, can bind multiple events, each event can specify multiple callback functions, can be decouples, conducive to the realization of modularity disadvantages: the whole program has to become event-driven, the running process will become unclear

4. The Generator function

Meaning: Generator functions are an asynchronous programming solution provided by ES6, and their syntactic behavior is completely different from that of traditional functions. Basic usage:

    function* helloGenerator() {
      yield 'hello';
      yield 'Generator';
      return 'over';
    }
    
    let hw = helloGenerator();
    hw.next() // {value:"hello",done:false}
    hw.next() // {value:"Generator",done:false}
    hw.next() // {value:"over",done:true}
    hw.next() // {value:undfined,done:true}
Copy the code

Features:

  1. There is an asterisk between the function keyword and the function name;
  2. Use yield expressions inside the function body to define different internal states.
  3. The next method was used to obtain the return results of each section of state, and the Gennrator function was performed for four times above. The first time, the first yield function is returned and paused. Done :false indicates that the state within the function has not finished executing. The second time, the same thing; Done :true indicates that the state within the function has been executed. The fourth time, THERE are no executable states in the function. Therefore, I return to undpay, and am informed that the states in the function have been executed. If there is no return in the function, I return undpay, done:true means that the status in the function has been completed.

5. Async functions (recommended)

The async function is introduced in the ES2017 standard to make asynchronous operations more convenient.

function get1(){
  return new Promise((resolve,reject) = >{
    setTimeout(() = >{
      resolve(1)},2000)})}async function getSet(){
  const n = await get1()
  //const n = await '111'
  return n
}
getSet().then(console.log)
Copy the code

Description:

  1. The await command can only be used in async functions, and an error will be reported if it is used in normal functions.
  2. “Await” is followed by a Promise object, such as get1 return Promise instance; If it is not a Promise object, the corresponding value is returned, such as ‘111’.
  3. The Promise object is fulfilled, and the Promise object is fulfilled with the value X, then the return value is X. The Promise object is fulfilled with the exception E, and the Promise object is fulfilled with the exception E
  4. A Promise returned by an async function will not change its state until all the Promise objects behind the internal await command have been executed. If any Promise object following an await statement goes reject or encounters a return, the entire async function is interrupted.
  5. Await will cause async function to suspend execution until the Promise has been resolved; If we want to not interrupt subsequent asynchronous operations even if the previous one fails. We can then put the first await in a try… Inside the catch structure, so that the second await is executed regardless of whether the asynchronous operation succeeds or not.
async function f() {
  try {
    await Promise.reject('Wrong');
  } catch(e) {

  }
  return await Promise.resolve('hello world');
}

f().then(v= > console.log(v))
Copy the code
function getData() {
  return new Promise((resolve, reject) = > {
    setTimeout(() = > {
      let name = '明明'
      resolve(name)
    }, 100);
  });
}

async function test() {
  let newData = await getData()
  console.log(newData)
}
test()
/ / it
Copy the code

Advantages: Async functions have four improvements over Generator functions

  1. Built-in executor: The execution of Generator functions must rely on next() for each module execution. Async has its own executor and only needs to be called as normal functions
  2. Better semantics: async means there is an asynchronous operation in a function, and await means that the following expression needs to wait for the result.

The return value is Promise: Async returns a Promise object that can be used to specify the next action. Moreover, async functions can be regarded as the operation of multiple asynchronous functions, wrapped into a Promise object, and await command is the syntactic sugar of internal THEN command, i.e. Promise.all() usage; Asynchronous operations following multiple await commands, if there is no secondary relationship, it is best to let them fire simultaneously.

    // Omit getFoo() and getBar()
    
    / / write one
    async function getSet(){
        let [foo, bar] = await Promise.all([getFoo(), getBar()]);
        return [foo, bar]
    }

    / / write two
    async function getSet(){
        let fooPromise = getFoo();
        let barPromise = getBar();
        let foo = await fooPromise;
        let bar = await barPromise;
        return [foo, bar]
    }
Copy the code