JavaScript Asynchronous Programming--async/await vs Promise

Source: Internet
Author: User
Tags error handling

compatibility

To remind you, Node now supports async/await from version 7.6. And just a few days ago, Node 8 has been officially released and you can use it with confidence.

If you haven't tried it yet, here's a bunch of examples of reasons why you should take it right away and never look back.

async/await

For those who have never heard of this topic, here is a simple 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 getJSON returns one promise , and the promise completion value is some JSON object. We just want to call it and output the JSON, and then return "done" .

Here is the code implemented with promise:

Const MAKEREQUEST = () =    Getjson ()      = {      console.log (data)    return "Done"  })    makerequest ()

And that's what it async/await looks like:

Const MAKEREQUEST = Async () = {      Console.log (await Getjson ())      return "Done" c20/>}    makerequest ()
 

Here are some differences:

    1. There is a keyword in front of the function async . awaitkeywords 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" ).

    2. The above point implies that we cannot use the top level of the code await , because it is not async within the function.

// This code cannot be executed  at the top level // await MakeRequest ()   // This code can be executed    = =      {//  do  something})

3. await getJSON() means that the console.log call waits until getJSON() promise finishes and prints out its value.

Why async/await better? 1. Simple and clean

See how much code we write less! Even in the man-made example above, it is clear that we are saving a lot of code. We do not have to write .then , create an anonymous function to handle the response, or give a name to a variable that is not needed data . We also avoided code nesting. These small advantages can accumulate quickly and become more pronounced in the subsequent code.

2. Error handling

Async/await will eventually allow us to use the same structure ( try/catch ) to process synchronous and asynchronous code into possibilities. In the example below using promise, if it fails, it will JSON.parse try/catch not be processed because it occurs in a prmoise. We need to raise the promise and .catch 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{Getjson (). Then (Result= {          //This parse may failConst DATA =json.parse (Result) console.log (data)}) //uncomment this block to handle asynchronous errors  //. catch (Err) = {    //Console.log (Err)    // })  }Catch(Err) {Console.log (Err)}}
 

Now look at the code implemented with async/await. Now the catch block will handle parsing errors.

Const MAKEREQUEST = Async () = {   try//  This parse will fail       const DATA =  Json.parse (await Getjson ()) 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  Getjson ()          = {          if (data.needsanotherrequest) {              return  makeanotherrequest (data)                      = {                      Console.log (moredata)               return moredata          })           Else {              console.log (data)              return  data          }}    )  }

This code looks a headache to people. It simply propagates the final results to the main promise, but it's easy to get lost in nesting (6 layers), curly braces, and return statements.

Rewrite This example with async/await, and it becomes easier to read.

Const MAKEREQUEST = Async () = {    = await Getjson ()    if  ( Data.needsanotherrequest) {      = await makeanotherrequest (data);      Console.log (moredata)      return  moredata    Else  {      Console.log (data)      return  data    }  }

4. Median value

You may find yourself in a state where you call your 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  promise1 ()      = {          // Do something            return Promise2 (value1)               = =              {//  do  something                return  promise3 (value1, value2)})}        )   }

If you promise3 don't need it value1 , it's easy to flatten the promise nesting. If you're the kind of person you can't stand, you might like the following, Promise.all containing values 1 and 2 in one, and avoiding deeper nesting:

Const MAKEREQUEST = () = {      return  promise1 ()          = {              // Do something              return Promise.all ([Value1, Promise2 (value1)])          })       = =          {//  do  something        return  promise3 (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. This will make you wonder about all the things you've done to make promise look less scary.

Const MAKEREQUEST = Async () = {      = await promise1 ()      = await Promise2 (value1)       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.

Const MAKEREQUEST = () = {      returncallapromise (). Then (()=callapromise ()). Then (()=callapromise ()). Then (()=callapromise ()). Then (()=callapromise ()). Then (()= {          Throw NewError ("oops"); })} makerequest ().Catch(Err ={console.log (err); //Output    //error:oops at CallAPromise.then.then.then.then.then (index.js:8:13)})
 

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 ()      thrownew Error ("oops");  }  MakeRequest ()      . Catch (err = {      console.log (err);       // Output      // error:oops at MakeRequest (index.js:7:9)  })

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:

    1. You cannot set breakpoints in an arrow function that returns an expression (no function body).

Const MAKEREQUEST = Async () ={    await callapromise () await    callapromise ()    await callapromise ()    await callapromise ()   //Try set a breakpoint here     await callapromise ()}

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.

Summary

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.

concern

You may have some legitimate doubts about using this feature:

    • It makes asynchronous code less obvious: Our eyes have learned that it takes a few weeks to adapt to the new flag as long as you see the callback or .then recognize the async code.

    • Don't worry about Node7 non-LTS version support, because node 8 is now out and will be the next LTS version, and migrating our codebase to the new version is likely to be effortless.

Recommended

Here is an article on Cnode Introducing async/await:http://cnodejs.org/topic/5640b80d3a6aa72c5e0030b6

JavaScript Asynchronous Programming--async/await vs Promise

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.