“This is the fourth day of my participation in the August Gwen Challenge.

preface

Promises introduced in ES6 can better solve the problem of callback hell, but the essence of then() method is still a callback function, and promises are still difficult to understand and master. In the process of learning promises, many people tend to think that promises are too difficult. I would rather face callback hell than learn promise, which shows that the more complex promise syntax was introduced to solve the problem of callback functions, so for this reason ES7 has introduced async/await as a better solution for asynchronous programming. True asynchronous programming logic can be written synchronously. Async /await looks synchronous but is asynchronous and non-blocking when executed in the background. Note of course that the async/await implementation is based on promises and generators.

Connection and advantages of async, await and Generator

  • Built-in actuators. Generator functions must be executed by an executor, hence the CO module, while async functions have their own executor. In other words, async functions perform exactly as normal functions do. Unlike Generator functions, you need to call the next method or use the CO module to actually execute and get the final result.
  • 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.
  • Wider applicability.coModule convention,yieldA command can only be followed by a Thunk function or a Promise object. whileasyncFunction of theawaitThe command can be followed by a Promise or a value of primitive type (Number, string, Boolean, but this is equivalent to a synchronous operation)
  • The return value is Promise.asyncThe return value is a Promise object, which is more convenient than the Iterator returned by Generator functions and can be used directlythen()Method is called.

Further, 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.

Async keyword

1. The async keyword is generally not used alone, but with await. An async function may have one or more await inside. The async function returns a Promise object, and callbacks can be added using the then method.

async function  test() {
    return '111'
};
test().then( (v) = > console.log(v)) / / 111
Copy the code

2. Serial and parallel. The state of Promise objects returned by async functions will not change until all Promise objects of await commands inside have been executed

That is, the callback to the then method is executed only when all asynchronous operations within an async function have been executed.

const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout)); async function f(){ await delay(2000); await delay(3000); await delay3000); return 'ok'; } f().then(v => console.log(v)); // Wait 8s before printing 'OK'Copy the code

In practice, it is important to note that if you have three Ajax requests, it will take 8s to complete the request, which is not acceptable. If you want to execute in parallel, the correct thing to do is to use the promise.all() method:

const delay = timeout= > new Promise(resolve= > setTimeout(resolve, timeout));
async function f(){    
    let p1 = delay(2000); 
    let p2 = delay(3000);
    let p3 = delay(3000);
    await Promise.all([p1, p2, p3]); 
    return 'ok';
}

f().then(v= > console.log(v)); // wait 3s before output 'ok'
Copy the code

Normally, the await command is followed by a Promise, and if it is not, it is converted to an immediately resolve Promise as in this example:

async function  f() {
    return await 1
};
f().then( (v) => console.log(v)) // 1
Copy the code
  1. Error handling

Use a try/catch method to catch errors, which is more flexible than the promise-catchf () method.

function sleep(second) {
    return new Promise((resolve, reject) = > {
        setTimeout(() = > {
            reject('want to sleep~'); }, second); })}async function errorDemo() {
    let result = await sleep(1000);
    console.log(result);
}
errorDemo();// VM706:11 Uncaught (in promise) want to sleep~

// To handle promise. reject we should wrap the block in a try catch
async function errorDemoSuper() {
    try {
        let result = await sleep(1000);
        console.log(result);
    } catch (err) {
        console.log(err);
    }
}

errorDemoSuper();// want to sleep~
// With a try catch we can get the promise. reject data back.
Copy the code

conclusion

  • promiseThe syntax is difficult to understand, and to solve the problem of asynchronous programming, a more complex promise syntax was introduced, sopromiseNot the ultimate solution for asynchronous programming.
  • GeneratorAlthough asynchronous programming with synchronous code is implemented, it must rely on the executor, which needs to pass every timenext()To carry out.
  • Async and awaitThe syntax is simple, and asynchronous programming is realized by synchronous code. It appears to be synchronous, but the background execution is asynchronous and non-blocking, and has better semantics than Generator.

Refer to the article

Understanding async/await