Home>Article>Web Front-end> The ins and outs of async/await

The ins and outs of async/await

hzc
hzc forward
2020-06-15 09:53:16 2594browse

Preface

During the interview, async/await is a good way to see the candidate's knowledge. Of course, I didn't think about what angle to explain this knowledge point. When asked by the interviewer, you can answer the syntax sugar of the self-executing generator. But have I realized it a little bit, or have I seen his realization?

How babel is implemented

Note: If you don’t know about generator, you can take a look at generator first, and by the way, you can take a look at iterator.

ex code:

async function t() { const x = await getResult(); const y = await getResult2(); return x + y; }

babel conversion 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); }

As can be seen from the code,babelconverts ageneratorForasync, two steps are used,_asyncToGeneratorandasyncGeneratorStep.

_asyncToGeneratorWhat did

1. Calling_asyncToGeneratorreturned apromise, which happened to be consistent withasyncFunctions can be connected tothenfeatures.

2. Define a successful method_nextand define a failed method_throw. In the two functions,asyncGeneratorStepis called. After readingasyncGeneratorStep, you will know that this is actually a recursion.

3. Execute_next. That is the self-executing generator mentioned above.

asyncGeneratorStepWhat it did

1. Try-catch to capture errors during the execution ofgenerator. If an error is reported, theasyncfunction will directly enter therejectstatus.

2. Determine whether thedonevalue ininfois true. If true, it means that the iterator has been executed. You canresolve the valuego out. Otherwise, continue to call_nextto pass the value to the next one.

这里我唯一没有看明白的是`_throw`,这个看代码像是执行不到的。promise.resolve状态值应该是fulfilled。看懂的 可以在评论中和我说一下,感谢。

Advantages of async/await

Whenever a new syntactic sugar appears, it must make up for the shortcomings of the previous generation solution.

ex: The appearance of

promise is to avoidcallback hell. The way to avoid it is to chain calls.

What does async/await solve?


The necessity of replacing promise with async/await

Synchronous way of handling asynchronous

async/await is closer to synchronization style, while promise uses the then method. Compared with async/await, the code will become larger, and there is not much difference between async/await and synchronization functions. However, there is still a gap in the writing method of promise.

Promise and async/await code comparison

promise version

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

async/await version

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

Intermediate value

When using promises, you will find that when multiple promises are serialized, it is very difficult for the subsequent promise to obtain the value of the previous promise. And async solves this problem exactly.

Example of promise to obtain intermediate value

const morePromise = () => { return promiseFun1().then((value1) => { return promiseFun2(value1).then((value2) => { return promiseFun3(value1, value2).then((res) => { console.log(res); }) }) }) }

The above is a nested version, which may not be nested according to different needs.

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

There is less nesting level, but it is still not satisfactory.

Using async/await optimization example

const morePromise = async function() { const value1 = await promiseFun1(); const value2 = await promiseFun2(value1); const res = await promiseFun3(value1, valuw2); return res; }

Serial asynchronous processes must involve intermediate values, so the advantages of async/await are obvious.

The situation of conditional statements

For example, there is currently a requirement. After you have requested a piece of data, you can then determine whether you need to request more data. There will still be nested levels when implemented using promises.

const a = () => { return getResult().then((data) => { if(data.hasMore) { return getMoreRes(data).then((dataMore) => { return dataMore; }) } else { return data; } }) }

But using async to optimize this example can make the code more beautiful.

async/await optimization example

const a = async() => { const data = await getResult(); if(data.hasMore) { const dataMore = await getMoreRes(data); return dataMore; } else { return data; } }

Disadvantages of async/await

We have talked about some of the advantages of async/await above, but async/await is not omnipotent. . The above are all about serial asynchronous scenarios. When we turn into a parallel asynchronous scenario. It is still necessary to use promise.all to implement

Parallel asynchronous scenarios

const a = async function() { const res = await Promise.all[getRes1(), getRes2()]; return res; }

async/await error handling

async/await in error capture The main aspect is try-catch.

try-catch

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

promise’s catch

You can extract a public function to do this. Because each promise is followed by catch processing, the code will be very lengthy.

const a = async function() { const res = await Promise.reject(1).catch((err) => { console.log(err); }) }
// 公共函数 function errWrap(promise) { return promise().then((data) => { return [null, data]; }).catch((err) => { return [err, null]; }) }

Recommended tutorial: "JS Tutorial"

The above is the detailed content of The ins and outs of async/await. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete