JavaScript Async code callbacks to Hell and the promise solution provided by jquery.deferred

Source: Internet
Author: User

Let's take a look at some of the frequently encountered problems in writing Ajax coding:

1. Since Ajax is asynchronous, all code that relies on Ajax return results must be written in the Ajax callback function. This inevitably forms the nesting, the more asynchronous operations such as Ajax, the deeper the nesting level, the poorer the code readability.

$.ajax ({    url:url,    data:dataobject,    success:function () {console.log ("I depend on Ajax result.");    error:function () {}}); Console.log ("I'll print before Ajax finished.");

2. If there is a dependency between AJAX requests, our code will form Pyramid of Doom (Pyramid Doom). For example, we want to accomplish such a thing: There are 4 URL addresses for AJAX access, need to first AJAX access 1th, after the 1th access is completed, with the return data obtained as parameters and then access 2nd, 2nd after the completion of the visit 3rd ... With this to 4 all accesses complete. In this way, it seems to be the case:

$.ajax ({    url:url1,    success:function (data) {        $.ajax ({            url:url2,            data:data,            success: function (data) {                $.ajax ({                    //...});});}    );

3. Consider this scenario, if we send two AJAX requests at the same time and then do one more thing after the two requests have been successfully returned, think about how difficult it is to attach the callback in the respective call location only in the previous way?


You can see that asynchronous operations like Ajax in JavaScript lead to complex nesting levels, poor readability, and sometimes even the need to implement the requirements are very difficult. In order to solve the problem of this asynchronous callback, COMMONJS organization developed the Asynchronous Pattern programming specification promises/a. At present, the specification has a lot of implementations, such as Q, When.js, jquery.deffered () and so on. We learn the promise with jquery.deffered.


The state of Promise

The Promise object has 3 possible states: a positive State (resolved), a negative state (rejected), and a wait state (pending). The Promise object that you just started to create is in the pending state, only from pending to resolved or from pending to rejected state.

var df1 = $. Deferred (); Console.log (Df1.state ());//pendingvar DF2 = $. Deferred (); Df2.resolve ();//resolvedconsole.log (Df2.state ()); var df3 = $. Deferred (); Df3.reject (); Console.log (Df3.state ());//rejected
$. Deferred () Creates a deferred object (that is, the Promise object), and Deferred.state () can get the current state of the Promise object. Deferred.resolve () and Deferred.reject () are used to change the state of the Promise object.

Promise Adding a callback function

There are 3 states of the Promise object, and we can register the callback function for each of the 3 states. When the promise is in a certain state, it triggers the registered callback function in this state.

var df = $. Deferred (); Df.done (function () {alert ("Success");}); Df.fail (function () {alert ("fail");}); Df.progress (function () {Alert ("Progress");}); Df.notify ();d f.resolve ();//Df.reject ();
Done (), fail (), Progress () register the callback function in resolved, rejected, pending state respectively. Pre-registered callback functions can be triggered by resolve (), Reject (), notify ().

Promise is supported for chained calls, the above code can be written as follows.

var df = $. Deferred (); Df.done (function () {alert ("Success");}). Fail (function () {alert ("fail");}). Progress (function () {Alert ("Progress");});


Promise supports multiple callback functions, which are called in the order of registration.

var df = $. Deferred (); Df.done (function () {alert ("First");}). Fail (function () {alert ("fail");}); Df.done (function () {alert ("Second");}); Df.done (function () {alert ("Third");}); Df.resolve ();


Deferred.always () The callback function that is added, whether promise is resolved state or rejected state, will be called.

var df1 = $. Deferred (); Df1.always (function (type) {alert (type);}); Df1.resolve ("resolve"); var df2 = $. Deferred (); Df2.always (function (type) {alert (type);}); Df2.reject ("reject");

Progress () and notify () can be used to implement a progress bar effect because notify () allows calls multiple times, while reject () and resolve () can only be called once. This is well understood, because once the state becomes resolved or rejected, it is no longer possible to change its state, nor is it necessary.

var df = $. Deferred ();   Df.done (function () {alert ("Success");});  Df.fail (function () {alert ("fail");});  Df.progress (function () {Alert ("Progress");});    Resolve () calls 2 times, but only 1 times successdf.resolve () is triggered;  Df.resolve ();  var mudf = $. Deferred ();   Mudf.done (function () {alert ("Success");});  Mudf.fail (function () {alert ("fail");});  Mudf.progress (function () {Alert ("Progress");});    Each call to notify will trigger the progress callback function mudf.notify ("%10");  Mudf.notify ("%20");  

There is no difference between rejectwith (), Resolvewith (), Notifywith () functions and reject (), resolve (), notify (), the main difference being the execution context in the callback function (this in the method) and the Parameter form. Specific differences can be found in the "Jquery.callbacks series one: API use detailed" in this article Fire () and Firewith ().


The above simply describes how promise is used, and we can write Ajax code in a promise way. It is easy to see that code nesting levels are low after using promise, and the code is growing vertically rather than growing horizontally. And with promise, you can specify multiple AJAX callback functions.

Old Ajax notation $.ajax ({url: "test.html", Success:function () {alert ("Success");  }, Error:function () {alert ("error"); }});//Use Promise after $.ajax ("test.html"). Done (function () {}). Fail (function () {}). Do (function () {). Fail (function () {);

the deferred object in jquery differences from promise objects

Jquery. deferred related APIs, some return deferred objects, and some return promise objects. Most functions, such as done (), reject (), return the deferred object, and the $.when () and then () functions return the Promise object. Refer to the jquery API documentation for details.

The official jquery explanation for Promise objects is:

This object provides a subset of the methods of the Deferred object (then, done, fail, always, progress, state and promise To prevent users from changing, the state of the Deferred.

You can see that the Promise object is actually part of the deferred object, and the deferred object provides a way to change the state, such as notify, reject, resolve, but the Promise object does not provide these methods.


The article begins with the Ajax problem, and problem 1 can easily be solved by promise. Issue 2 and Issue 3 are addressed through $.when () and Deferred.then (), as these 2 APIs are relatively complex, and later articles analyze these 2 APIs.


Reference articles

" Asynchronous JavaScript and promise "author Acgtofe



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

JavaScript Async code callbacks to Hell and the promise solution provided by jquery.deferred

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.