This article mainly introduces Deferred of deferred in jQuery. the promise () method reminds you to pay attention to deferred. promise () and jQuery's. the difference between promise () instance methods. For more information, see
Deferred. promise () and. promise ()
These two APIs have almost the same syntax, but there is a big difference. Deferred. promise () is a method of the Deferred instance. It returns a Deferred. Promise instance. A Deferred. the Promise object can be understood as a view of the deferred object. It only contains a set of methods of the deferred object, including: done (), then (), fail (), isResolved (), isRejected (), always (). These methods can only observe the state of a deferred object, but cannot change the internal state of the deferred object. This is very suitable for API encapsulation. For example, the owner of a deferred object can control the state (resolved or rejected) of the deferred object as needed, but can return the Promise object of the deferred object to other observers, the observer can only observe the changes in the State and bind the corresponding callback function, but cannot change the internal state of the deferred object, thus providing good isolation protection.
Deferred. promise ()
$(function(){ // var deferred = $.Deferred(); var promise = deferred.promise(); var doSomething = function(promise) { promise.done(function(){ alert('deferred resolved.'); }); }; deferred.resolve(); doSomething(promise); })
Deferred. promise () can also accept an object parameter. At this time, the imported object will be assigned to the Promise method and returned as a result.
// Existing object var obj = { hello: function( name ) { alert( "Hello " + name ); } }, // Create a Deferred defer = $.Deferred(); // Set object as a promise defer.promise( obj ); // Resolve the deferred defer.resolve( "John" ); // Use the object as a Promise obj.done(function( name ) { this.hello( name ); // will alert "Hello John" }).hello( "Karl" ); // will alert "Hello Karl"
Deferred. promise () only prevents other code from changing the state of the deferred object. It can be understood that, through deferred. the deferred promise object returned by the promise () method is a method that can change the state without resolve, reject, progress, resolveWith, rejectWith, and progressWith. You can only use done, then, fail and other methods to add handler or determine the status.
Deferred. promise () does not change the state of the deferred object, nor does it ensure the current State remains unchanged. It only ensures that you cannot pass the deferred. the deferred promise object returned by promise () changes the state of the deferred object. If we directly return the dtd in this place, it can also work. The. done processing function will still be executed after dtd. resolve.
For the blog example, if we change the code to the following format:
Var dtd = $. Deferred (); // create a new deferred object var wait = function (dtd) {var tasks = function () {alert ("execution completed! "); Dtd. resolve (); // change the execution status of the deferred object}; setTimeout (tasks, 5000); return dtd ;};$. when (wait (dtd )). done (function () {alert ("Haha, success! ") ;}). Fail (function () {alert (" error! ");});
The execution result is the same as the result of dtd. promise returned previously.
What is the difference? If we change the code for $. when to the following:
Var d = wait (dtd); $. when (d). done (function () {alert ("Haha, success! ") ;}). Fail (function () {alert (" error! ") ;}); D. resolve ();
We will find alert ("Haha, success !") It will be executed immediately, but it will take 5 seconds to pop up after the execution is completed.
However, if we use the wait function to return dtd. promise () HERE d. resolve (), an error will be reported because the object d does not have the resolve () method.
Similarly, if we change the code:
Var dtd = $. Deferred (); // create a new deferred object var wait = function (dtd) {var tasks = function () {alert ("execution completed! "); Dtd. resolve (); // change the execution status of the deferred object}; setTimeout (tasks, 5000); return dtd. promise () ;}; dtd. resolve (); $. when (wait (dtd )). done (function () {alert ("Haha, success! ") ;}). Fail (function () {alert (" error! ");});
We can also find alert ("Haha, success !") It will be executed immediately, because the dtd deferred object has been resolve () before it is passed into wait, and the state of the deferred object will not change once it is resolve or reject.
Then we can change the code $. wait:
$. When (wait (dtd). done (function () {alert ("Haha, success! ") ;}). Fail (function () {alert (" error! ") ;}); Dtd. resolve ();
We will also find alert ("Haha, success !"); Executed immediately. Although the dtd has not been resolve when the wait (dtd) is executed, and the response of the wait method is dtd. promise (), but the original dtd deferred object is exposed, and we can change its status from the outside.
Therefore, if we really don't want other code to change the state of the deferred object inside the wait method, we should write it as follows:
Var wait = function () {var dtd = $. Deferred (); // create a new deferred object var tasks = function () {alert ("execution completed! "); Dtd. resolve (); // change the execution status of the deferred object}; setTimeout (tasks, 5000); return dtd. promise () ;}; $. when (wait ()). done (function () {alert ("Haha, success! ") ;}). Fail (function () {alert (" error! ");});
That is, do not expose deferred directly, and finally return deferred. promise (), so that the code in other places can only add handler.
. Promise ()
This is not a method for Deferred instances first! This method is used by jQuery instances. This method is used to return a Promise object after a group of actions (such as animations) are completed, so that the event listener can listen to its status and execute corresponding processing functions.
This method accepts two optional parameters:. promise ([type,] [target])
Type: queue type. The default value is fx. fx is the animation of the jQuery object.
TargetObject: the object that you want to grant Promise behavior,
These two parameters are optional. Currently, the first parameter (I) has no value types except fx. Therefore, it is generally used for animation monitoring and some operations are performed after the animation is completed.
Example: A promise object in the resolved State is directly returned without any animation effect.
Var p = $ (""); P. promise (). done (function (arg1) {// alert will be triggered immediately (this = p & arg1 = p );});
Example: trigger the done () Listener function after all animation effects are completed