Code for using the deferred object in jquery 1.5 (translation) _jquery

Source: Internet
Author: User

Translator Note:
1. Deferred is a new feature of jQuery1.5, many people translate it into "asynchronous queue", I think it is more reliable, after all, and "delay" does not matter, but this article I also use the word Deferred.

2. This article is mentioned in the jQuery1.5 blog, and is also the current introduction of deferred more classic and in-depth articles. In view of the present Chinese information is relatively few, specially translates for everybody to study the reference.

3. the use of free translation throughout the way, if there is improper also invited you to raise.

The new Deferreds object in jQuery1.5 can be used to decouple the processing of a task's completion from the task itself. This is nothing new in the JavaScript community, because the MochiKit and dojo two JS frameworks have been implemented for a long time. But as Julian Aubourg rewrite the Ajax modules in jQuery1.5, Deferreds naturally became the internal implementation logic. With the Deferreds object, multiple callback functions can be bound to execute when the task completes, and can even bind the callback functions after the task completes. These tasks can be asynchronous or synchronized.

More importantly, Deferreds has been implemented as an internal implementation of $.ajax (), so you can automatically get the traversal that Deferreds brings when invoking Ajax. For example, we can bind the callback function like this:

Copy Code code as follows:

$.get, asynchronous Ajax request
var req = $.get (' foo.htm '). Success (function (response) {
Ajax successful processing functions
}). Error (function () {
Ajax failed Post handler function
});
This function may be invoked before the end of Ajax
Dosomethingawesome ();
Add another Ajax callback function, at which point the Ajax may have ended, perhaps not yet.
Because $.ajax has built-in support for deferred, so we can write
Req.success (function (response) {
This function will be invoked at the end of Ajax, or be called immediately if Ajax is over
});

We are no longer limited to a single successful, failed or completed callback function. Instead, the callback functions that are added at any time are placed in a first-in, first-out queue.
From the example above, the callback function can be attached to an AJAX request (any observable task observable tasks), even if the AJAX request has ended. The organization of the Code is good, and we don't have to write a long callback function anymore. This is like $.queue () has encountered Pub/sub (publish subscription mechanism, generally used in the event-based model).
More deeply, imagine a scenario in which a callback function is executed after a few concurrent Ajax requests have ended. I can easily do this through the function $.when () of jquery:
Copy Code code as follows:

function Doajax () {
Return $.get (' foo.htm ');
}

function Domoreajax () {
Return $.get (' bar.htm ');
}

$.when (Doajax (), Domoreajax ()). Then (function () {
Console.log (' I fire once BOTH Ajax requests have completed! ');
}). Fail (function () {
Console.log (' I fire if one or more requests failed. ');
});

In JsfiddleOpen example in

The above example works correctly, thanks to the Ajax method return value of each jquery contains a promise function to track asynchronous requests. The return value of the Promise function is a read-only view of the deferred object. (Thepromise is a read-only viewto the result of the task.) Deferreds determines whether the current object is observable by detecting whether there is a promise () function in the object. $.when () waits for all AJAX requests to end, and then invokes the callback function that is registered by the. then (),. Fail () (the specific call to which callback function depends on the end state of the task). These callback functions are executed in accordance with their registration order.

Better yet, $.when () accepts a function or an array of functions as a parameter (translator Note: This is not right, $.when accepts one or more deferred objects, or native JS objects.) Note that you cannot use a function array as an argument, so you can assemble these asynchronous tasks at will.

$.ajax () returns an object that associates some deferred functions, such as Promise (), then (), Success (), error (). However, you cannot manipulate the original deferred object, only the Promise () function (the translator Note: Remember the promise read-only view) and the isrejected () and isresolved () functions that can detect the deferred state.

But why not return the deferred object? If the complete deferred object is returned, then we have more control and may be able to trigger it randomly (translator: I translate resolve to trigger, which triggers all callback functions registered to the deferred object) deferred object, This causes all callback functions to execute before the end of the AJAX request. therefore, in order to avoid the risk of not expecting to trigger deferred, we should only return Dfd.promise (). (therefore, to avoid potentially breaking the whole Paradigm, just return the Dfd.promise ().) (Translator Note: If you are confused about the exact meaning of the above paragraphs, it doesn't matter, I'll write an article to analyze the reason
Register callback function (registering callbacks)
In the example above, we use the then (), Success (), fail () method to register the callback function, but there are more ways to use it, especially when processing AJAX requests. Which method you use depends on your focus on the status of the results.
All deferred objects have functions (AJAX, $.when, or manually created deferred objects):

Copy Code code as follows:

. Then (Donecallbacks, Failedcallbacks)
. Done (Donecallbacks)
. Fail (failcallbacks)

The Ajax object contains 3 additional methods, two of which are mapped to the method mentioned above. These methods are primarily intended to be compatible with previous code:
Copy Code code as follows:

"Success" and "error" are mapped to two methods of "done" and "fail" respectively
. Success (Donecallbacks)
. Error (Failcallbacks)

You can also register a complete callback function that will be invoked at the end of the request, regardless of whether the request was successful or failed. Unlike success or the error function, the complete function is actually an alias of the done function of a single deferred object. The deferred object created inside the $.ajax () will trigger the callback function (resolve) After the end of Ajax.
Copy Code code as follows:

. Complete (Completecallbacks)

Therefore, the following 3 examples are equivalent (in the context of Ajax, success looks more comfortable than the done function, right?). In fact, it is because we are familiar with the previous Ajax invocation, preconceived, or thinking stereotypes:
Copy Code code as follows:

$.get ("/foo/"). Done (FN);
Equivalent to:
$.get ("/foo/"). Success (FN);
Equivalent to:
$.get ("/foo/", FN);

Create your own Deferred object (creating your own Deferred)
We know that $.ajax and $.when implement the deferred interface internally, but we can also create deferred objects by hand:
Copy Code code as follows:

function GetData () {
Return $.get ('/foo/');
}
function Showdiv () {
var DFD = $. Deferred ();
$ (' #foo '). FadeIn (1000, dfd.resolve);
return Dfd.promise ();
}
$.when (GetData (), Showdiv ()). Then (function (Ajaxresult) {
Console.log (' The animation and the AJAX request are both done! ');
' Ajaxresult ' is the server-side return (translator Note: The result of Ajax in GetData)
});

In JsfiddleOpen example in
In Showdiv (), we created a deferred object, performed an animation, and then returned to promise. The deferred object is triggered (resolved) after the end of the Fadein (). In this promise returns and deferred objects (note: Here the deferred refers to the $.when created object rather than the Showdiv () returned object) in the middle of the trigger, a then () callback function is registered. This callback function is executed after all two asynchronous tasks have ended.
GetData () returns an object (which is actually a jquery-encapsulated XMLHttpRequest object) that has the Promise method, which allows $.when () to monitor the end of this Ajax request. The manually steps we took to return a promise in Showdiv () are handled for us internally by $.ajax () and $.when ().
1/15/2011:julian in the commentary that the above syntax can be reduced to $. Deferred (FN). Promise (). So the following two-sided code is equivalent:
Copy Code code as follows:

function Showdiv () {
var DFD = $. Deferred ();
$ (' #foo '). FadeIn (1000, dfd.resolve);
return Dfd.promise ();
}
Equivalent to:
function Showdiv () {
Return $. Deferred (function (DFD) {
$ (' #foo '). FadeIn (1000, dfd.resolve);
}). Promise ();
}

Add a callback function for a custom deferred object (Defer your deferreds)
We can go further and register the callback function for GetData () and Showdiv (), as we register the callback function in $.then (). (Translator Note: The following paragraph content repeat, said is a meaning, do not translate, look at the code)
Copy Code code as follows:

function GetData () {
Return $.get ('/foo/'). Success (function () {
Console.log (' Fires after the AJAX request succeeds ');
});
}
function Showdiv () {
Return $. Deferred (function (DFD) {
Translator Note: This code is not in the original, but it appears in the Jsfiddle.
I think it's the author's intention to register the callback function for the custom deferred function
Dfd.done (function () {
Console.log (' Fires after the animation succeeds ');
});
$ (' #foo '). FadeIn (1000, dfd.resolve);
}). Promise ();
}
$.when (GetData (), Showdiv ()). Then (function (Ajaxresult) {
Console.log (' Fires after BOTH showdiv () and the AJAX request succeed! ');
' Ajaxresult ' is the result of the server return
});

In JsfiddleOpen example in
Chain code (chaining hotness)
Deferred callback functions can be chained, as long as the function returns a deferred object (Dfd.promise () returns a read-only deferred object). This is an actual code (via @ajpiano!)
Copy Code code as follows:

function Savecontact (row) {
var form = $.tmpl (templates["Contact-form"]),
Valid = True,
Messages = [],
DFD = $. Deferred ();
/*
* Here's how the client-side validation code
*/
if (!valid) {
Dfd.resolve ({
Success:false,
Errors:messages
});
} else {
Form.ajaxsubmit ({
DataType: "JSON",
Success:dfd.resolve,
Error:dfd.reject
});
}
return Dfd.promise ();
};
Savecontact (Row). Then (function (response) {
if (response.success) {
Client-side validation passed, and the data was saved successfully
} else {
Client validation failed
Output error message
}
}). Fail (function (ERR) {
Ajax request failed
});

The Savecontact () function first verifies the validity of the form data and then saves the validity state in the variable valid. If validation fails, direct deferred will be triggered (pass a JS object containing the success status code and error information as a parameter to the callback function). If validation passes, the data is submitted to the server and the deferred object is triggered when the Ajax completes successfully. Fail () Handles HTTP status codes 404, 500, and so on that can prevent AJAX requests from completing successfully.
Non-observable task (non-observable tasks)
Deferreds is useful for decoupling tasks and task processing functions, whether asynchronous or synchronous. A task may return promise, but it can also return a string, object, or other type.
In this example, when the "Lanch application" link is first clicked, an AJAX request is sent to the server and the current timestamp is returned. The timestamp is then saved to the data cache of the link. When this link is clicked again, it simply takes the timestamp back from the cache without making an AJAX request.
Copy Code code as follows:

function StartTask (Element) {
var timestamp = $.data (element, ' timestamp ');
if (timestamp) {
return timestamp;
} else {
Return $.get ('/start-task/'). Success (function (timestamp) {
$.data (element, ' timestamp ', timestamp);
});
}
}
$ (' #launchApplication '). Bind (' click ', Function (event) {
Event.preventdefault ();
$.when (StartTask (this)). Done (function (timestamp) {
$ (' #status '). HTML (' <p>you-Started-Task on: ' + timestamp + ' </p> ');
});
Loadapplication ();
});

When $.when () discovers that its first argument has no promise function (and therefore is not observable), it creates a new deferred object, triggers the deferred object, and returns the promise read-only object. As a result, any task that is not observable can be passed to $.when ().
One problem to note is that if an object itself owns the Promise function, then that object will not be a deferred object. jquery Determines whether an object is deferred by looking at whether it has a promise function, but jquery does not check whether the promise really returns an object that is available. So the following code will have an error:
Copy Code code as follows:

var obj = {
Promise:function () {
Do something
}
};
$.when (obj). then (FN);

Conclusion (conclusion)
Deferreds proposes a new, robust way to handle asynchronous tasks. Unlike the traditional process of organizing code into a callback function, the new deferred object allows us to bind multiple callback functions at any time (even after the task ends), and these callback functions are invoked in a first-in, first-out manner. The information in this article may be more difficult to digest, but once you have mastered the use of the deferred object, you will find that the code that the organization asynchronously executes will be very easy.
This article by the original Sansheng Stone, blog Park starting, reproduced please indicate the source

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.