Es6 -- new promise ()

Source: Internet
Author: User

What is promise? Is it an object? Array? Function? We can print it out directly, console. dir (promise)

It can be seen that promise is a constructor, which has the "all", "reject", and "resolve" methods on its own, and the then and catch methods on its prototype. In this case, the then and catch methods must be applied to the objects created by using promise. Let's try again.

  

VaR P = new promise (function (resolve, reject) {// do some asynchronous operations setTimeout (function () {console. log ('execution completed '); resolve ('whatever data') ;}, 2000 );});

The constructor of promise receives a parameter, which is a function and passes in two parameters: resolve and reject, which respectively indicate the callback function after the asynchronous operation is successful and the callback function after the asynchronous operation fails to be executed. In fact, the description of "success" and "failure" is not accurate here. according to standards, resolve sets the promise status to fullfiled, And the reject sets the promise status to rejected. However, we can understand this in the initial stage, and then look at the concept in detail later.

In the above Code, we executed an asynchronous operation, that is, setTimeout. After 2 seconds, we output "execution completed" and called the resolve method.

After the code is run, "execution completed" will be output in 2 seconds ". Note! I just added a new object and didn't call it. The function we passed in has been executed. This is a special detail. So when we use promise, we usually package in a function and run this function as needed, such:

Function runasync () {var P = new promise (function (resolve, reject) {// perform some asynchronous operations setTimeout (function () {console. log ('execution completed '); resolve ('whatever data') ;}, 2000) ;}); return P ;} runasync ()
View code

So we have two questions: 1. What is the purpose of packaging a function? 2. What is resolve ('whatever data?

At the end of the packaged function, the promise object will be returned. That is to say, to execute this function, we get a promise object. Do you still remember that the promise object has the then and catch methods? This is the power. See the following code:

Runasync (). then (function (data) {console. log (data); // you can use the uploaded data to perform other operations //......});
View code

The then method is called directly on the response of runasync (). Then receives a parameter, which is a function and gets the parameter passed when resolve is called in runasync. When this code is run, "execution completed" will be output in 2 seconds, followed by "whatever data ".

At this time, we will find that the functions in then are just like our usual callback functions, which can be executed after the runasync asynchronous task is executed. This is the role of promise. Simply put, it is to separate the original callback Writing Method and run the callback function in a chain call method after the asynchronous operation is completed.

So it cannot be mentioned that the callback function is encapsulated. Is it different for the runasync to be passed in, as shown below:

Function runasync (callback) {setTimeout (function () {console. log ('execution completed '); callback ('whatever data');}, 2000);} runasync (function (data) {console. log (data );});
View code

What is a callback function? It is to pass a function A as a parameter of another function B and call function a in function B to process the data obtained by function B in function.

The same is true, but it is still difficult to use promise. So the question is, what should I do with multi-layer callbacks? What if callback is also an asynchronous operation and a corresponding callback function is required after execution? No more callback2 can be defined, and then passed to callback. The advantage of promise is that it can relay the promise object in the then method and return it, and then continue to call then for callback.

Chained operation usage

Therefore, on the surface, promise can only simplify the writing of layer-by-layer callback. In essence, the essence of promise is "State ", the callback function can be called in a timely manner by maintaining the status and passing the status, which is much simpler and more flexible than passing the callback function. Therefore, the correct scenario for promise is as follows:

runAsync1().then(function(data){    console.log(data);    return runAsync2();}).then(function(data){    console.log(data);    return runAsync3();}).then(function(data){    console.log(data);});
View code

In this way, the content in each asynchronous callback can be output every two seconds, and the data transmitted to resolve in runasync2 can be obtained in the next then method. The running result is as follows:

How are the three functions runasync1, runasync2, and runasync3 defined? As follows:

Function runasync1 () {var P = new promise (function (resolve, reject) {// perform some asynchronous operations setTimeout (function () {console. log ('asynchronous Task 1 execution completed '); resolve ('whatever data 1');}, 1000);}); Return P;} function runasync2 () {var P = new promise (function (resolve, reject) {// do some asynchronous operations setTimeout (function () {console. log ('asynchronous Task 2 execution completed '); resolve ('whatever data 2');}, 2000);}); Return P;} function runasync3 () {var P = new promise (function (resolve, reject) {// do some asynchronous operations setTimeout (function () {console. log ('asynchronous Task 3 Execution completed '); resolve ('whatever data 3') ;}, 2000) ;}); return P ;}
View code

In the then method, you can also directly return the data instead of the promise object. In the subsequent then, you can receive the data. For example, we can modify the above Code to the following:

Runasync1 (). then (function (data) {console. log (data); Return runasync2 ();}). then (function (data) {console. log (data); Return 'Return data directly '; // return data directly here }). then (function (data) {console. log (data );});
View code

The output is like this:

Reject usage

We only use resolve. Now let's take a look at reject. In fact, the previous example only shows the "successful execution" Callback, and there is no "failure, the role of reject is to set the promise status to rejected, so that we can capture it in then and then execute the callback in case of "failure. See the following code.

 

Function getnumber () {var P = new promise (function (resolve, reject) {// perform some asynchronous operations setTimeout (function () {var num = math. ceil (math. random () * 10); // generate a random number from 1 to 10 if (Num <= 5) {resolve (Num );} else {reject ('Number too big ') ;}, 2000) ;}); return P ;}getnumber (). then (function (data) {console. log ('refreshed'); console. log (data) ;}, function (reason, data) {console. log ('objected'); console. log (reason );});
View code

The getnumber function is used to obtain a number asynchronously. It will be executed after 2 seconds. If the number is smaller than or equal to 5, we think it is "successful" and call resolve to modify the promise status. Otherwise, we think it is "failed". Call reject and pass a parameter as the cause of failure.

Run getnumber and pass two parameters in then. The then method can accept two parameters. The first one corresponds to the resolve callback and the second one corresponds to the reject callback. So we can get the data they sent. Run this code multiple times and you will get the following two results randomly:

 

Catch usage

We know that in addition to the then method, the promise object also has a catch method. What is it used? In fact, it is the same as the second parameter of then and used to specify the callback of the reject. The usage is as follows:

 

getNumber().then(function(data){    console.log(‘resolved‘);    console.log(data);}).catch(function(reason){    console.log(‘rejected‘);    console.log(reason);});
View code

The effect is the same as that written in the second parameter of then. However, it has another role: when executing the resolve callback (that is, the first parameter in the preceding then), if an exception is thrown (the Code fails), it will not be stuck, but will enter the catch method. See the following code:

Getnumber (). then (function (data) {console. log ('refreshed'); console. log (data); console. log (somedata); // somedata is not defined here }). catch (function (reason) {console. log ('objected'); console. log (reason );});
View code

In the resolve callback, we console. Log (somedata); while the somedata variable is not defined. If we don't need promise, the error will be reported directly on the console when the code runs here, rather than running it down. However, the following result is displayed:

That is to say, it goes into the Catch Method and transmits the cause of the error to the reason parameter. Even if there is an error code, no error will be reported, which has the same function as our try/catch statements.

 All usage

The All method of promise provides the ability to execute asynchronous operations in parallel, and callback is executed only after all asynchronous operations are completed. We still use the three defined functions runasync1, runasync2, and runasync3. Let's look at the example below:

 

Promise.all([runAsync1(), runAsync2(), runAsync3()]).then(function(results){    console.log(results);});
View code

Execute with promise. All. All receives an array parameter, and the values in it are finally returned with the promise object. In this way, the parallel execution of the three asynchronous operations will not be completed until they are all executed. So where are the data returned by the three asynchronous operations? All in then, all will put the results of all asynchronous operations into an array and pass them to then, that is, the above results. Therefore, the output result of the above Code is:

With all, You can execute multiple asynchronous operations in parallel and process all returned data in One callback. Is it cool? One scenario is suitable for this scenario. Some games have a lot of materials. When you open a webpage, You can pre-load the various resource fragments, Flash files, and various static files you need. After all the files are loaded, initialize the page.

Usage of race

The effect of the All method is actually "who runs slowly, and who executes the callback based on who executes the callback, because this is the result that enters then after all parallel operations are completed 」, there is another method, "who runs fast, and who executes the callback". This is the race method. The usage of race is the same as that of all. Let's change the latency of runasync1 to 1 second:

Promise.race([runAsync1(), runAsync2(), runAsync3()]).then(function(results){    console.log(results);})
View code

These three asynchronous operations are also executed in parallel. As you can guess, runasync1 will be executed after 1 second, so only runasync1 data will be executed. The result is as follows:

Note that runasync2 () and runasync3 () are not stopped when the callback in then starts to be executed. So a second later, they output their ending mark.

What is the purpose of this race? There are still many application scenarios. For example, we can use race to set a timeout time for an asynchronous request and execute corresponding operations after the timeout. The Code is as follows:

// Request an image resource function requestimg () {var P = new promise (function (resolve, reject) {var IMG = new image (); IMG. onload = function () {resolve (IMG);} IMG. src = 'xxxxxx';}); Return P;} // latency function, used to time the request. function timeout () {var P = new promise (function (resolve, reject) {setTimeout (function () {reject ('image request timeout') ;}, 5000) ;}); return P ;} promise. race ([requestimg (), timeout ()]). then (function (results) {console. log (results );}). catch (function (reason) {console. log (reason );});
View code

The requestimg function asynchronously requests an image and writes the address to "xxxxxx". Therefore, the request cannot be sent successfully. The timeout function is an asynchronous operation with a latency of 5 seconds. We put the two functions that return the promise object into the race, so they will race. If the image request is successful within five seconds, go to the then method again and execute the normal process. If the image has not been returned in five seconds, the timeout will win, and the system will catch the result and return the message "image request timeout. The running result is as follows:

 

Summary: Is es6 promise just like this? Yes, this is basically what can be used.
How have I met done, finally, success, fail, etc? These are not in the promise standard, but the syntactic sugar we implement.

Es6 -- new 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.