Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the async/await of JavaScript

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how to understand the async/await of JavaScript. The content of the article is of high quality, so the editor shares it for you as a reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.

With the release of Node 7, more and more people begin to study async/await, which is said to be the ultimate solution for asynchronous programming. I have seen this set of keywords not in the JavaScript language, but in the syntax of c # 5.0. The async/await of C # needs to be used in version 4.5 of the .NET Framework, so I was sad for a while-in order to be compatible with the XP system, the software we developed could not use a version later than the .NET Framework.

Async/await is a great feature in both C# and JavaScript, and they are also very sweet syntax sugars. The async/await implementation of C # is inseparable from the Task or Task class, and the async/await implementation of JavaScript is also inseparable from Promise.

Now put aside C# and .NET Framework and concentrate on the async/await of JavaScript.

What are async and await doing?

Any name is meaningful, so let's take it literally. Async is an abbreviation for "asynchronous", while await can be thought of as an abbreviation for async wait. So it should be well understood that async is used to declare that an function is asynchronous, while await is used to wait for an asynchronous method execution to complete.

There is also an interesting syntax that states that await can only appear in async functions. Then a careful friend will have a question, if await can only appear in the async function, then how should the async function be called?

If you need to call an async function through await, you must wrap another async function on the outside of the call, and then. Enter the endless cycle, never rise to the top.

If the async function does not need to be called by await, what exactly is the role of async?

What is the role of async

The crux of the question is how the async function handles its return value!

We certainly want it to return the value we want directly through the return statement, but if that's the case, there seems to be nothing wrong with await. So, write a piece of code to see what it returns:

Async function testAsync () {return "hello async";} const result = testAsync (); console.log (result)

It dawned on me when I saw the output-- the output was a Promise object.

C:\ var\ test > node-- harmony_async_await. Promise {'hello async'}

So, the async function returns a Promise object. This information can also be obtained from the documentation. The async function (including function statements, function expressions, Lambda expressions) returns a Promise object, and if you return a direct quantity in the function, async will encapsulate the direct quantity into a Promise object through Promise.resolve ().

The async function returns a Promise object, so when the outermost layer cannot get its return value with await, of course we should handle the Promise object in the original way: the then () chain, like this

TestAsync () .then (v = > {console.log (v); / / output hello async})

In retrospect, what if the async function does not return a value? It's easy to think that it will return Promise.resolve (undefined).

Think of the characteristic of Promise-no wait, so when you execute the async function without await, it executes immediately, returns a Promise object, and never blocks subsequent statements. This is no different from a normal function that returns a Promise object.

So the next key point is the await keyword.

What exactly is await waiting for?

Generally speaking, it is thought that await is waiting for an async function to complete. However, according to the syntax, await is waiting for an expression that evaluates to a Promise object or other value (in other words, without special qualification).

Because the async function returns a Promise object, await can be used to wait for the return value of an async function-- it can also be said that await is waiting for the async function, but be clear that what it is waiting for is actually a return value. Note that await is not only used to wait for Promise objects, it can wait for the result of any expression, so await can actually be followed by ordinary function calls or direct quantities. So the following example works perfectly correctly

Function getSomething () {return "something";} async function testAsync () {return Promise.resolve ("hello async");} async function test () {const v1 = await getSomething (); const v2 = await testAsync (); console.log (v1, v2);} test ()

Await waited for what he had to wait for, and then what?

Await waits for what it's waiting for, a Promise object, or some other value, and then what? I have to say first that await is an operator that is used to make up an expression, and the result of the operation of an await expression depends on what it and so on.

If it does not wait for a Promise object, then the await expression evaluates to what it waits for.

If it waits for a Promise object, await is busy, blocking the rest of the code, waiting for the Promise object resolve, and then getting the value of resolve as the result of the await expression.

You panicked when you saw the word blockage above. Don't worry, this is why await must be used in the async function. The async function call does not cause blocking, and all blocking within it is encapsulated asynchronously in a Promise object.

What did async/await do for us?

Make a simple comparison

It has been explained that async will encapsulate the return value of the subsequent function (function expression or Lambda) into a Promise object, while await will wait for the Promise to complete and return the result of its resolve.

Now, for example, using setTimeout to simulate time-consuming asynchronous operations, let's first see how to write without async/await

Function takeLongTime () {return new Promise (resolve = > {setTimeout () = > resolve ("long_time_value"), 1000);} takeLongTime () .then (v = > {console.log ("got", v);})

If you switch to async/await, it will be like this.

Function takeLongTime () {return new Promise (resolve = > {setTimeout () = > resolve ("long_time_value"), 1000);} async function test () {const v = await takeLongTime (); console.log (v);} test ()

Sharp-eyed students have found that takeLongTime () is not declared as async. In fact, takeLongTime () itself is the returned Promise object, and whether you add async or not, the result is the same. If you don't understand, please go back and see "what does async do?"

Another question arises, these two pieces of code, the two ways of handling asynchronous calls (actually the handling of Promise objects) is not obvious, and even need to write more code to use async/await, so what is its advantage?

The advantage of async/await is that it handles then chains.

A single Promise chain does not discover the advantages of async/await, but if you need to deal with multiple Promise chains of then, you can. (interestingly, Promise uses then chains to solve the problem of multi-layer callbacks, and now uses async/await to further optimize it.)

Suppose a business is completed in multiple steps, each of which is asynchronous and depends on the results of the previous step. We still use setTimeout to simulate asynchronous operations:

/ * pass in the parameter n, indicating the time it takes for this function to execute (in milliseconds) * the result is n + 200.This value will be used in the next step * / function takeLongTime (n) {return new Promise (resolve = > {setTimeout () = > resolve (n + 200), n);} function step1 (n) {console.log (`step1 with ${n} `); return takeLongTime (n) } function step2 (n) {console.log (`step2 with ${n} `); return takeLongTime (n);} function step3 (n) {console.log (`step3 with ${n}`); return takeLongTime (n);}

Now use Promise to implement the processing of these three steps

Function doIt () {console.time ("doIt"); const time1 = 300; step1 (time1) .then (time2 = > step2 (time2)) .then (time3 = > step3 (time3)) .then (result = > {console.log (`result is ${result} `); console.timeEnd ("doIt");} doIt () / / c:\ var\ test > node-- harmony_async_await. / / step1 with 300 / / step2 with 500 / / step3 with 700 / / result is 900 / / doIt: 1507.251ms

The output result is the parameter 700200 = 900of step3 (). DoIt () performs three steps in sequence, taking a total of 300,500,700 = 1500 milliseconds, consistent with the console.time () / console.timeEnd () calculation.

If you use async/await to implement it, it will be like this.

Async function doIt () {console.time ("doIt"); const time1 = 300; const time2 = await step1 (time1); const time3 = await step2 (time2); const result = await step3 (time3); console.log (`result is ${result} `); console.timeEnd ("doIt");} doIt ()

The result is the same as the previous Promise implementation, but does this code look much clearer, almost as much as synchronous code

There's something even cooler.

Now changing the business requirements is still three steps, but each step requires the result of each previous step.

Function step1 (n) {console.log (`step3 with ${n} `); return takeLongTime (n);} function step2 (m, n) {console.log (`step2 with ${m} and ${n}`); return takeLongTime (m + n);} function step3 (k, m, n) {console.log (`step3 with ${k}, ${m} and ${n} `); return takeLongTime (k + m + n);}

This time, use async/await to write:

Async function doIt () {console.time ("doIt"); const time1 = 300; const time2 = await step1 (time1); const time3 = await step2 (time1, time2); const result = await step3 (time1, time2, time3); console.log (`result is ${result} `); console.timeEnd ("doIt");} doIt (); / / c:\ var\ test > node-- harmony_async_await. / / step1 with 300 / / step2 with 800 = 300 + 500 / / step3 with 1800 = 300 + 1000 / / result is 2000 / / doIt: 2907.387ms

Except that the execution time is getting longer, it seems to be no different from the previous example. Don't worry, think about what it would be like if you wrote it into Promise.

Function doIt () {console.time ("doIt"); const time1 = 300; step1 (time1) .then (time2 = > {return step2 (time1, time2) .then (time3 = > [time1, time2, time3]);}) .then (times = > {const [time1, time2, time3] = times; return step3 (time1, time2, time3) }) .then (result = > {console.log (`result is ${result} `); console.timeEnd ("doIt");} doIt ()

Does it feel a little complicated? That pile of parameter processing is the dead point of the Promise scheme, parameter transmission is too troublesome, look dizzy!

This is the end of the async/await on how to understand JavaScript. I hope the above content can be helpful to you and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report