Explain Promise in big vernacular and understand Promise in jquery

Source: Internet
Author: User

Let's say $. Deferred

jquery with $. Deferred implements the promise specification, $. What the hell is deferred? Or the old way, print out to see, first have a visual impression:

Javascript

1

2

var def = $. Deferred ();

Console . Log (def) ;


The output is as follows:


$. Deferred () Return an object, we can call it the Deferred object, hanging some familiar methods such as: Done, fail, then, etc. jquery uses this deferred object to register the callback function of an asynchronous operation, modifying and passing the state of the asynchronous operation.

The basic usage of the deferred object is as follows, in order not to be confused with Ajax, we still cite the settimeout example:

Javascript

1

2

3

4

5

6

7

8

9

10

11

12

function runasync(){

var def = $. Deferred ();

//Do some asynchronous operations

settimeout(function(){

Console. Log (' execution completed ') ;

def. Resolve (' random data ') ;

};

return def;

}

Runasync (). then (function(data){

Console. Log (data)

});


In the Runasync function, we first define a Def object, then perform a delay operation, call Def.resolve () after 2 seconds, and finally return the DEF as a function. The Def object is returned when the Runasync is invoked, and then we can. Then to execute the callback function.


Does it feel like ES6 's promise? Let's recall the example of ES6 in the first article:

Javascript

1

2

3

4

5

6

7

8

9

10

11

function runasync(){

var p = new Promise (function(resolve, reject) {

//Do some asynchronous operations

settimeout(function(){

Console. Log (' execution completed ') ;

Resolve(' random data ');

};

    });

return p;           

}

Runasync ()


The difference is a matter of knowing where to look. Since the Def object of jquery itself has a resolve method, we do not pass a function argument like ES6 when we create a Def object, which is empty. This call can be directly def.resolve () in the following way.


This also has a disadvantage, because the implementation of Runasync () can get the Def object, and Def object on the Resolve method, then it is not possible to modify the status of Def on the outside? For example, I modified the above code as follows:

Javascript

1

2

3

4

5

var d = Runasync ();

D . then (function(data){

Console. Log (data)

});

D . Resolve (' on the outside End ') ;


What is the phenomenon? It does not output "execute completion" after 2 seconds, but instead outputs "end at outside" directly. Because we did not wait for his own resolve before the execution of the asynchronous operation was completed, we gave resolve the outside. This is obviously risky, such as an asynchronous operation that you define and a callback function that you specify, and it is possible that your callback function will not be executed if it is terminated prematurely by someone else.


What to do? jquery provides a promise method, on a Def object, where he can return a restricted deferred object that is restricted without resolve or reject and cannot change his state from the outside, using the following:

Javascript

1

2

3

4

5

6

7

8

9

function runasync(){

var def = $. Deferred ();

//Do some asynchronous operations

settimeout(function(){

Console. Log (' execution completed ') ;

def. Resolve (' random data ') ;

};

return def. Promise (); //Just call here

}


There is no resolve method on the returned object, and there is no way to change his state from the outside. This promise name from a little exotic, easy to confuse us, in fact, he is a return of restricted deferred object method, and promise norms have no relationship, just the name is called Promise. Although the name is wonderful, but recommended use.


Chained calls to Then

Since deferred is also an implementation of the promise specification, other features must also be supported. The use of chained calls is as follows:

Javascript

1

2

3

4

5

6

7

8

9

10

11

12

13

var d = Runasync ();

D . then (function(data){

Console. Log (data) ;

return RunAsync2 ();

})

. then (function(data){

Console. Log (data) ;

return runAsync3 ();

})

. then (function(data){

Console. Log (data) ;

});


As is the case in our first article, we can refer to it.


Done and Fail

As we know, in the Promise specification, the then method accepts two parameters, respectively, for execution completion and failure of execution, and enhancements in jquery, as well as a third parameter, which is the callback in the pending state, as follows:

Javascript

1

deferred then donefilter [ failfilter [ progressfilter


In addition, jquery added two syntactic sugar methods, done and fail, to specify a callback for execution and execution failures, i.e. this code:

Javascript

1

2

3

4

5

D . then (function(){

Console. Log (' execution completed ') ;

}, function(){

Console. Log (' execution failed ') ;

});


is equivalent to this code:

Javascript

1

2

3

4

5

6

D . Done (function(){

Console. Log (' execution completed ') ;

})

. fail (function(){

Console. Log (' execution failed ') ;

});


The use of Always

There is also a always method on the deferred object of jquery, which always executes regardless of execution or execution failure, somewhat like the complete in Ajax. Don't repeat it.

The use of $.when

In jquery, there is also a $.when method to implement the promise, which, like the All method function in ES6, performs asynchronous operations in parallel, executing the callback function after all the asynchronous operations have been executed. But $.when is not defined in $. Deferred, see the name on the know, $.when, it is a separate method. Slightly different from the parameters of the ES6 all, it accepts not arrays, but multiple deferred objects, as follows:

Javascript

1

2

3

4

5

$ when runasync runasync2 runasync3 ) Span class= "Crayon-sy"-

. then (function(data1, data2 , Data3){

Console. Log (' full execution complete ') ;

Console. Log (data1, data2 , data3) ;

});


Isn't there a race method in jquery like ES6? That's the way to run fast. Yes, it's not in jquery.


This is the common method of deferred objects in jquery, and there are some other methods that are not used much, simply do not remember it. Now it's time to talk about Ajax.

The relationship between Ajax and deferred

jquery Ajax returns a restricted deferred object, remember the restricted deferred object, that is, there is no resolve method and reject method, can not change the state from the outside. Think about it too, you send an AJAX request, others from other places to cancel you off, it is also unbearable.

Since it's a deferred object, all of the features we've talked about above, Ajax are also available. For example, chained calls that send multiple requests consecutively:

Javascript

1

2

3

4

5

6

7

8

9

10

11

12

13

req1 = function(){

return $. Ajax (/*...*/) ;

}

REQ2 = function(){

return $. Ajax (/*...*/) ;

}

req3 = function(){

return $. Ajax (/*...*/) ;

}

req1 (). then (req2) . then (req3) . Done (function(){

Console. Log (' send request completed ') ;

});


Understand the essence of the Ajax return object, then we can use it handy.


Success, error and complete

These three methods may be the most we use, the use of this is:

Javascript

1

2

3

4

$ . Ajax (/*...*/)

. Success (function(){/*...*/})

. Error (function(){/*...*/})

. Complete (function(){/*...*/})


Represents a callback that succeeds, fails, and ends the AJAX request. What is the relationship between these three methods and deferred? In fact, is the grammar of sugar, success corresponding done,error corresponding fail,complete always, so, just in order to be consistent with the number of Ajax parameters, more convenient for everyone to remember, look at the source code:

Javascript

1

2

3

deferred . Promise ( jqxhr ) . Complete = completedeferred. Add ;

JQXHR . Success = jqxhr. Done ;

JQXHR . Error = jqxhr. fail ;


Complete that line to write, is to reduce the duplication of code, in fact, is to do and fail again, and always the same code. Deferred.promise (JQXHR) also shows that Ajax returns a restricted deferred object.


jquery adds all these grammatical sugars, although the threshold of entry is lower, but it creates a certain degree of confusion. Some people have been writing for a long time, but have been unaware of the principle, in the interview can only answer some of the fur, this is very bad. That's why I wrote this article.

JQuery Deferred object involves a lot of methods, this article as far as possible to introduce a variety of categories, hoping to help you to clarify the thinking. Summed up is: $. Deferred implements the promise specification, then, done, fail, always is the method of deferred object. $.when is a global approach to running multiple asynchronous tasks in parallel, with ES6 all being a feature. Ajax returns a deferred object, success, error, complete is the syntax candy provided by Ajax, function and deferred object's done, fail, always consistent. On the sauce.


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.