Reference: http://www.10tiao.com/html/558/201705/2650964601/1.html
Node now supports async/await starting with version 7.6.
Brief introduction:
Async/await is a new way of writing asynchronous code. The scenarios for the previous async code are callbacks and promise.
Async/await is actually built on the basis of promise. It cannot be used with normal callbacks or node callbacks.
Async/await, like promise, is also non-blocking.
Async/await makes asynchronous code look and behave more like synchronous code. This is where its power lies.
Grammar:
Suppose the function Ajax returns a promise, and the promise's completion value is some JSON object. We just want to invoke it and output the JSON, and then return "done".
Here is the code implemented with Ajax:
varajax=NewPromise (function(resolve,reject) {$.ajax ({type:"POST", URL:"List.php", Success:function(Result) {/*result = {flag:true, msg: ', Data: []}*/ if(Result.flag) {resolve (Data.data)//called when the asynchronous operation succeeds}Else{reject (data.msg);//called when an asynchronous operation fails } } }); });
Here is the code implemented with promise:
Const MAKEREQUEST = () = ajax.then (data = { console.log (data); return "Done";})
MakeRequest ();
Here is the code implemented with async/await:
Const MAKEREQUEST = Async () = { Console.log (await Ajax); return ' Done ';}
Difference:
There is a keyword in front of the function async
. await
keywords are used only async
within defined functions. All async
functions implicitly return a promise, and promise's completion value will be the return value of the function (in this case "done"
).
It cannot be used at the top of the code await
, because it is not async
inside the function.
// await makerequest () This code cannot be executed at the top level // and the following code can execute makerequest (). Then (result ) = = {// do something })
3. await ajax
means that the console.log
call waits until ajax
promise finishes and prints out its value.
Async/await Advantages:
1. Simple and clean
Save a lot of code. Do not write .then
, create an anonymous function to handle the response, or give a name to a variable that is not needed data
. Code nesting is also avoided. These small advantages can accumulate quickly and become more pronounced in the subsequent code.
2. Error handling
Async/await will eventually make it try/catch
possible to process synchronous and asynchronous code with the same structure (). In the example below using promise, if it fails, it will JSON.parse
try/catch
not be processed because it occurs in a prmoise. Need to be raised on promise .catch
and repeat the error handling code. This error-handling code is more complex than the code that can be used in production console.log
.
Const MAKEREQUEST = () = = {try {= = { Console.log (result); }) Catch (Err) { // statements console.log (err); }}
Code implemented with async/await. Now the catch
block will handle parsing errors.
Const MAKEREQUEST = Async () = { try { // This will parse failed const Data = Json.parse (await Ajax); Console.log (data) catch (err) { console.log (err);} }
3. Conditional sentences
Suppose you want to do something like the following code, get some data, decide whether you should return the data, or get more details based on some of the values in the data.
Const MAKEREQUEST = () = { return ajax.then (data = { if ( Data.flag) { return makeanotherrequest (data). Then (Moredata = { Console.log ( Moredata); return moredata; }) Else { console.log (data);}} )}
This code looks a headache to people. It simply propagates the final result to the main promise, but it's easy to get lost in nesting, curly braces, and return statements.
Rewrite This example with async/await, and it becomes easier to read.
Const MAKEREQUEST = Async () = { = await Ajax; if (data.flag) { = await makeanotherrequest (data); Console.log (moredata); return moredata; Else { console.log (data);} }
4. Median value
Scenario: Call PROMISE1, then use its return value to invoke Promise2, and then use the results of these two promise to invoke PROMISE3. Your code is likely to look like this:
Const MAKEREQUEST = () = { return pomise1 (). Then (value1 = { return Pomise2 (). Then (value2 = { return pomise3 (value1, value2); })} )}
If you promise3
don't need it value1
, it's easy to flatten the promise nesting. Then it might look like this, Promise.all
with a value of 1 and 2 in one, and avoid deeper nesting:
Const MAKEREQUEST = () = { return pomise1 (). Then (value1 = { return Pomise.all ([ value1, promise2 (value1) = { return POMISE3 (value1, value2);} ) }
This method sacrifices semantics for readability. In addition to avoiding promise nesting, there is no reason to combine value1
and value2
incorporate an array.
But with async/await, the same logic becomes super simple and intuitive.
Const MAKEREQUEST = Async () = { = await promise1 (); = await Promise2 (); return promise3 (value1, value2);}
5. Error stack
If there is a chain of code that calls multiple promise, an error is thrown somewhere in the chain.
// error stack const MAKEREQUEST = () =>< Span style= "COLOR: #000000" > { return callapromise (). Then (() => Callapromise ()). Then (() => Callapro Mise ()). Then (() => Callapromise ()) . then (() => => { throw new Error (' opps ' ;)})} MakeRequest (). catch (Err =>
The error stack returned from the promise chain did not find clues as to where the error occurred. Worse, this is misleading; the only function name it contains is callAPromise
that it is completely unrelated to this error (although the file and line numbers are still useful).
However, the error stack from async/await points to the function that contains the error:
Const MAKEREQUEST = Async () = { await callapromise (); await Callapromise (); await Callapromise (); await Callapromise (); await Callapromise (); Throw New Error (' oops ');} makerequest (). Catch (err = { console.log (err);})
This is not a big deal when developing in the local environment and opening files in the editor, but it is useful when you want to figure out the error log from the production server. In this case, it is better to know that the error occurred in the makeRequest
middle than to know the error from one another then
.
6. Commissioning
Last but not least, when using async/await, a killer advantage is that debugging is easier. Debugging promise has been so painful for two reasons:
You cannot set breakpoints in an arrow function that returns an expression (no function body).
// Error Stack const MAKEREQUEST = () = { return callapromise (). then (() = Callapromise ( ) = callapromise ()) = callapromise ()) + callapromise ()) = = {thrownew Error (' opps ';) })}
Try setting a breakpoint here
2. If you .then
set a breakpoint in a block and use a debug shortcut like one step debugging, the debugger does not move to the back .then
because it only steps through the synchronization code.
With async/await, we don't need so many arrow functions, you can step through the await call just as you would a normal synchronous call.
Const MAKEREQUEST = Async () = { await callapromise (); await Callapromise (); await Callapromise (); await Callapromise (); await Callapromise (); Throw New Error (' oops ');}
Summarize
Async/await is one of the most revolutionary features added to JavaScript in the last few years. It gives us a sense of how chaotic the promise syntax is and provides an intuitive alternative.
The async\/await of JavaScript Promise the six