Because the article was written too late, a little sleepy, copy the wrong code, has been corrected.

In our last blog post, we covered promises in terms of actual use and interviews, but the Promise approach, while addressing callback hell, is full of Promise’s then() method, If the processing flow is complex, the entire code will be filled with THEN, and the code flow does not represent the execution flow well.

Why async/await

In ES6, we can use a Generator function to control the flow, as in this code:

function* foo(x) {
    yield x + 1;
    yield x + 2;
    return x + 3;
}Copy the code

We can control the flow of the function by repeatedly calling the next() method of the Generator object. But that doesn’t seem all that semantic. Therefore, the syntactic sugar async function for Generator functions is encapsulated in ES6, but defined in ES7. ES7 defines async functions, finally giving JavaScript the ultimate solution for asynchronous operations. Async functions are syntactic sugar for Generator functions. Async is represented with the keyword Async and await is used inside the function. Compared with Generator, Async functions are improved in the following aspects: Generator functions must be executed by an executor, while Async () functions come with an executor and are called in the same way as normal functions. Async and await are more semantic than * and yield. Async functions return Promise objects, which are more convenient than iterators returned by Generator functions and can be called directly using the then () method.

So, here’s a little code to illustrate the use of async/await functions:

Timing functions without async/await:

fn = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(1)
    }, 2000)
  })
}
const Fn = () =>{
  fn().then((res) => {
    console.log(res)
  })
}
Fn()
console.log(2)Copy the code

I’m sure every programmer who can see this knows what this code looks like: print 2,2 s and then print 1.

Timing functions with async/await:

fn = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(1)
    }, 2000)
  })
}
const Fn = async () => {
  await fn().then((res) => {
    console.log(res)
  })
  console.log(2)
}
Fn()

Copy the code

This part of the function prints 1 after 2s, then 2.

So, why?

We take the words async and await literally: async means async and async is used to define an asynchronous function that returns a Promise. ; ‘await’ means to wait, ‘Promise’ is a Promise and ‘await’ is a Promise. Promise promises to output the return value to then’s callback function, whether it succeeds or fails. The promise of await is that whether it is windy or raining, I will wait for you to finish doing other steps. Therefore, in the above async/await code, we wait for the FN to complete and for the asynchronous callback to complete processing of the return value before we proceed to the next operation. The idea is to turn an asynchronous function into a synchronous operation.

The practical application

In last week’s work, I used async/await many times to control the execution flow of the program in a crawler operation based on Node:

/ / pseudo codelet axiosArr = [];
for (let i = 0, len = arr.length; i < len; i++) {
  let params = qs.stringify({
    'param': Arr [I].index,}) axiosar.push (axios.post(url, params, {headers}))} On average 16 interfaces are accessed for each data * simultaneously queried with axios.all, processed with return value when return is complete * then stored in mongodb database */ await axios.all(axiosArr).then(axios.spread()function () {
    for (let i = 0, len = arguments.length; i < len; i++) {
      let str = `${unescape(arguments[i].data.replace(/\\u/g, '%u'))}`;
      str = basics.subStr(basics.deletN(basics.deletS(basics.cutStr(str))));
      concentArr[i].concent = str
    }
    mg.mongodbMain({
      name: obj.name,
      alias: obj.alias,
      type: type,
      url: obj.url,
      drugsConcent: concentArr
    })
  }))Copy the code

Actually, that’s it, and you’ll see it in the code. But the problem is that when I do not use async/await, I will get 2000+ data first, continuously accessing its 16 interfaces, but since the promise’s then callback function is asynchronous, it will hang instead of saving the data directly to the database. This is not what we were expecting. So I’m using async/await functions here, using synchronization to handle asynchronous operations, synchronizing the promise, and when AXIos. all accesses 16 interfaces of each piece of data, I store the data directly in the database, and then I go to the next level of the loop, which is the same 16 interfaces of the next piece of data.

After async/await

We said async returns a Promise object.

const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
    await delay(1000);
    await delay(2000);
    await delay(3000);
    return 'done'; } f().then(v => console.log(v)); // Print after 6s'done'Copy the code

If an exception is thrown internally, the state of the returned Promise object changes to Reject. An error thrown is received by the catch method callback.

async function e(){
    throw new Error('error'); } e().then(v => console.log(v)) .catch( e => console.log(e)); // Errors thrown will be caught by a catchCopy the code

In addition, async has a property similar to promise.all, which is that an await function is reported at an inner point and no further execution is performed

let fn1 = ()=>{
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            reject('Deliberately throwing an error'); }, 500); }); }let fn2 = ()=>{
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{ resolve(1); }, 500); }); }let getList = async ()=>{
    let a = await fn1();
    let b = await fn2();
    return{first: a,second:b}; } getList().then(result=> { console.log(result); }).catch(err=> { console.log(err); // Async status changed to rejected});Copy the code

When Promise came along, it was like the end of callback hell. Async is finally not a difficult thing to do when Async/Await comes along.