preface

In an interview async/await is one area of the candidate’s knowledge. Of course, he did not want to explain this knowledge point from what Angle. When asked in person, you can answer the syntax of the self-executing generator. But have you ever implemented it yourself, or have you ever seen it?

How does Babel work

Note: If you don’t know about Generator, you can look at Generator and iterator.

The ex code:

async function t() {
    const x = await getResult();
  	const y = await getResult2();
  	return x + y;
}
Copy the code
Babel transforms the code
"use strict";

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
        var info = gen[key](arg);
        var value = info.value;
    } catch (error) {
        reject(error);
        return;
    }
    if (info.done) {
        resolve(value);
    } else {
        Promise.resolve(value).then(_next, _throw); }}function _asyncToGenerator(fn) {
    return function () {
        var self = this, args = arguments;
        return new Promise(function (resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
            }
            function _throw(err) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
            }
            _next(undefined);
        });
    };
}

function t() {
  return _t.apply(this.arguments);
}

function _t() {
  _t = _asyncToGenerator(function* () {
    const x = yield getResult();
    const y = yield getResult2();
    return x + y;
  });
  return _t.apply(this.arguments);
}
Copy the code

As you can see from the code, Babel converts a generator to async in two steps: _asyncToGenerator and asyncGeneratorStep.

_asyncToGeneratorWhat did

1. Calling _asyncToGenerator returns a promise that async functions can follow then.

2, define a successful method _next, define a failed method _throw. The two functions call asyncGeneratorStep. So if you look at asyncGeneratorStep you know that this is actually a recursion.

3. Run _next. This is the self-executing generator mentioned above.

asyncGeneratorStepWhat did

1. Try-catch to catch errors during generator execution. If an error occurs, async is reject.

Check whether the done value in info is true. If it is true, the iterator has completed and the value of resolve can be resolved. Otherwise, the _next call continues to pass the value to the next one.

The only thing I don’t see here is’ _throw ‘, which looks like it can’t be executed. The promise state value should be fulfilled. You can tell me in the comments, thank you.

The advantage of async/await

Every time a new syntactic sugar appears, it is bound to make up for the shortcomings of the previous generation’s solution.

Ex:

Promises are created to avoid callback hell by making chained calls.

What is async/await to solve?


Replace several of the necessities of promise with async/await

The synchronous approach handles asynchrony

Async /await is closer to the style of synchronization, while promise uses the way of then. Compared with async/await, there will be more code, and async/await is not much different from synchronous function, so there is still a gap in the writing of promise.

Promise vs. async/await code

Promise version

function getData() {
    getRes().then((res) = > {
        console.log(res); })}Copy the code

Async/await

const getData = async function() {
    const res = await getRes();
    console.log(res);
}
Copy the code

The median

When we use promises, we will find that when multiple promises are serial, it is very difficult for subsequent promises to obtain the value of previous promises. Async solves this problem.

An example of a promise getting an intermediate value
const morePromise = (a)= > {
	return promiseFun1().then((value1) = > {
		return promiseFun2(value1).then((value2) = > {
			return promiseFun3(value1, value2).then((res) = > {
				console.log(res); })})})}Copy the code

Above is the nested version, may not be nested according to different requirements.

const morePromise = (a)= > {
	return promiseFun1().then((value1) = > {
		return promiseAll([value1, promiseFun2(value1)])
	}).then(([value1, value2]) = > {
		return promiseFun3(value1, value2).then((res) = > {
			console.log(res); })})}Copy the code

Less nesting levels, but still not as good as you’d like.

Optimize the example with async/await
const morePromise = async function() {
	const value1 = await promiseFun1();
	const value2 = await promiseFun2(value1);
	const res = await promiseFun3(value1, valuw2);
	return res;
}
Copy the code

In a serial asynchronous process, there must be intermediate values involved, so the advantages of async/await are obvious.

Conditional statements

For example, if you currently have a requirement, you can request one data and then decide if you need to request more data. Using promises to implement it will still result in nested hierarchies.

example
const a = (a)= > {
    return getResult().then((data) = > {
        if(data.hasMore) {
            return getMoreRes(data).then((dataMore) = > {
                returndataMore; })}else {
            returndata; }})}Copy the code

But using Async to optimize this example makes the code more elegant.

Async /await optimization example
const a = async() = > {const data = await getResult();
    if(data.hasMore) {
        const dataMore = await getMoreRes(data);
        return dataMore;
    } else {
        returndata; }}Copy the code

Async/await the disadvantage

We talked about several advantages of async/await above, but async/await is not a panacea. All of the above are serial asynchronous scenarios. When we move to a parallel asynchronous scenario. You still need to use promise.all

Parallel asynchronous scenario
const a = async function() {
    const res = await Promise.all[getRes1(), getRes2()];
    return res;
}
Copy the code

Error handling of async/await

Async /await mainly uses try-catch for error catching.

try-catch

const a = async() = > {try{
        const res = await Promise.reject(1);
    } catch(err) {
        console.log(err); }}Copy the code

The promise of catch

You can pull out a public function to do this. Because each promise is followed by a catch, the code can be very verbose.

const a = async function() {
    const res = await Promise.reject(1).catch((err) = > {
        console.log(err); })}Copy the code
// Public function

function errWrap(promise) {
    return promise().then((data) = > {
        return [null, data];
    }).catch((err) = > {
        return [err, null]; })}Copy the code

push

In the current epidemic situation, only entering large companies, graduates can have a good guarantee. Small companies will be forced to recruit passively if they are unable to survive, lay off workers or become permanent employees.

The writer works for Alibaba Retail Link. If you want to tweet in, you can email [email protected]. Massive HC!! You can also add the q group: 912253914. Edit your resume in your spare time.