JavaScript asynchronous scheme async/await instance tutorial

Source: Internet
Author: User
Tags exception handling http request

Building an application always faces asynchronous calls, either on the Web front-end interface or on the Node. js server side. It is always disgusting to process asynchronous calls in JavaScript. In the past, we had to use callback functions. Later, we gradually developed many solutions. Finally, Promise won the championship with simplicity, ease of use, and compatibility, but there are still many problems. In fact, JavaScript has always wanted to completely solve this problem at the language level. In ES6, it has supported native Promise, introduced the Generator function, and finally decided to support async and await in ES7.


Basic syntax

How does async/await solve the Asynchronous call statement? To put it simply, asynchronous operations are written in synchronous format. First, let's look at the most basic syntax (ES7 code snippet ):

Const f = () => {
Return new Promise (resolve, reject) => {
SetTimeout () => {
Resolve (123 );
},2000 );
});
};

Const testAsync = async () => {
Const t = await f ();
Console. log (t );
};

TestAsync ();

First, define a function f. This function returns a Promise with a latency of 2 seconds, resolve and a value of 123. The testAsync function uses the keyword async during definition, and then uses await in the function body to execute testAsync. The whole program will output 123 in 2 seconds, that is, the constant t in testAsync gets the resolve value in f, and blocks the subsequent code execution through await, until the asynchronous function f is executed.


Comparison of Promise

Just a simple call, we can see that async/await is powerful. When writing code, we can handle asynchronous functions very elegantly, and say goodbye to callback nightmares and countless then methods. Let's take a look at the comparison with Promise. If the same code is used completely, what is the problem?

Const f = () => {
Return new Promise (resolve, reject) => {
SetTimeout () => {
Resolve (123 );
},2000 );
});
};

Const testAsync = () => {
F (). then (t) => {
Console. log (t );
});
};

TestAsync ();

From the code snippet, it is not hard to see that Promise has not solved a good problem. For example, if there are many then methods, the entire code will be full of Promise methods, rather than the business logic itself, in addition, each then method has an independent internal scope. If you want to share data, you need to expose some data to the outermost layer and assign a value within then. Despite this, Promise is very good at encapsulating asynchronous operations, so async/await is based on Promise, and await is followed by a Promise instance.


Comparison with RxJS

RxJS is also very interesting. It is used to process asynchronous operations. It can better process stream-based data operations. For example, in Angular2, the http request returns an Observable Object constructed by RxJS. We can do this:

$ Http. get (url)
. Map (function (value ){
Return value + 1;
})
. Filter (function (value ){
Return value! = Null;
})
. ForEach (function (value ){
Console. log (value );
})
. Subscribe (function (value ){
Console. log ('Do something .');
}, Function (err ){
Console. log (err );
});

The ES6 code can be further concise:

$ Http. get (url)
. Map (value => value + 1)
. Filter (value => value! = Null)
. ForEach (value => console. log (value ))
. Subscribe (value) => {
Console. log ('Do something .');
}, (Err) => {
Console. log (err );
});

It can be seen that RxJS can perform stream-like processing on such data, which is also very elegant. What makes RxJS powerful is that you can also cancel, listen to, and throttle data, I will not give an example here. If you are interested, you can look at the RxJS API.

It should be noted that RxJS and async/await can also be used together. The Observable Object contains the toPromise method, which can return a Promise Object and can also be used in combination with await. Of course, you can also use async/await with underscore or other libraries to achieve elegant results. In short, RxJS does not conflict with async/await.


Exception handling

By using async/await, we can use try/catch to capture problems in asynchronous operations, including reject data in Promise.

Const f = () => {
Return new Promise (resolve, reject) => {
SetTimeout () => {
Reject (234 );
},2000 );
});
};

Const testAsync = () => {
Try {
Const t = await f ();
Console. log (t );
} Catch (err ){
Console. log (err );
  }
};

TestAsync ();

In the code snippet, change the resolve in the f method to reject. In testAsync, the reject data can be captured through catch, and the output err value is 234. When using try/catch, pay attention to the range and level. If the try range contains multiple await, the catch will return the value or error of the first reject.

Const f1 = () => {
Return new Promise (resolve, reject) => {
SetTimeout () => {
Reject (111 );
},2000 );
});
};

Const f2 = () => {
Return new Promise (resolve, reject) => {
SetTimeout () => {
Reject (222 );
},3000 );
});
};

Const testAsync = () => {
Try {
Const t1 = await f1 ();
Console. log (t1 );
Const t2 = await f2 ();
Console. log (t2 );
} Catch (err ){
Console. log (err );
  }
};

TestAsync ();

As shown in the code snippet, in the testAsync function body, try has two await functions, both of which are reject respectively. In catch, only reject of f1 is triggered, and the output err value is 111.


Start to use

Whether it is the Web front-end or Node. the js server can use ES6 and ES7 to write code by means of pre-compilation, currently, the most popular solution is to compile the code written in ES7 and ES6 into E6 or ES5 through Babel for execution.
Node. js server configuration

The simplest way for the server to use Babel is to use the require hook.

First install Babel:

$ Npm install babel-core -- save

Install async/await support:

$ Npm install babel-preset-stage-3 -- save

Configure the. babelrc file in the root directory of the server code. The content is:

{
"Presets": ["stage-3"]
}

Introduce the Babel module to the top-level code file (server. js or app. js:

Require ("babel-core/register ");

All modules introduced after this sentence will be automatically compiled by babel, but the current file will not be compiled by babel. In addition, you need to note the Node. js version. If it is 4.0 or later, most ES6 versions are supported by default and can be started directly. However, if the version is about 0.12, it must be started through node-harmory. Because of the stage-3 mode, Babel does not compile the basic ES6 code. Why should the environment be compiled to ES5 since it is supported? This is also done to improve performance and compilation efficiency.


Configure Web front-end construction

The pre-compiled tasks of Gulp can be added.

First install the gulp-babel plug-in:

$ Npm install gulp-babel -- save-dev

Then write the configuration:

Var gulp = require ('Gulp ');
Var babel = require ('gulp-babel ');
Gulp. task ('Babel ', function (){
Return gulp. src ('src/app. Js ')
. Pipe (babel ())
. Pipe (gulp. dest ('dist '));
});

In addition to the Gulp-babel plug-in, you can also use the official Babel-loader in combination with Webpack or Browserify.

It should be noted that although there are official pure browser versions of Babel. js, there are many browser restrictions, and the impact on the client performance is also great, it is not recommended to use.


LeanEngine Full Stack

LeanEngine is a server running environment launched by LeanCloud and supports Node. the js and Python environments are powerful and currently free of charge. Combined with the LeanCloud JavaScript SDK, the original complex development work becomes simple and efficient. Currently, apsaradb for Redis and overseas nodes are supported to easily meet your business needs.


LeanCloud uses its own services to compile many applications and Web products. To facilitate developers to develop applications based on LeanEngine, LeanCloud has compiled the current technical stack for developing Web products and launched a complete and practical technical solution based on the characteristics of LeanEngine: leanEngine-Full-Stack, which has been configured with Babel. You can use the JavaScript SDK in LeanEngine to process asynchronous operations using async/await. So what are you waiting? Download and compile a new project.

Enjoy!

Conclusion

LeanCloud hopes to help developers and entrepreneurs accelerate product development by building the most simple and easy-to-use technical products, and save resource, time, and opportunity costs as much as possible. I hope this article will help you. If you have any questions, you can submit the issue in the LeanEngine-Full-Stack @ GitHub repository, or directly go to the LeanCloud community to ask questions.

Related Article

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.