How to be more elegant writing JavaScript farewell callback back to Hell (on)

Source: Internet
Author: User

Recently too Busy, originally a weekly article, one months also did not write an article. Hey!
Next, the intention of the blog to make a revision, may change the blog address, good earnest writing articles, the future of the blog content will be divided into the following several directions:

Bloggers write their own technical articles
Foreign technical Articles Translation
Bo main spit groove, sense, egg-like article
I wish I could do it well.

What is a callback to hell?

PS: Some Daniel said, there is no multi-layer callback nesting, write more people will have.

Here's an example

When using the jquery Animat to do multiple animations, many of the children's shoes may have written the following code.

The code is as follows Copy Code
After the previous animation completes, the next animation is executed immediately after execution
$ (' xx '). Animate ({xxxx}, function () {
$ (' xx '). Animate ({xx},function () {
Do something
},1000)
},1000)

As you can see from the above code, there are currently 2 levels of callback nesting.
So let's think about it, if we have 3, 4, or more animations to execute immediately,
Did we find that I was caught in an endless callback to hell?

You can visit here to see some of the callbacks we usually write. More examples: Callback in JS code hell

So, here, you see, a lot of callback functions are nested,
Not only makes the code look uglier and bloated, it also makes the project more and more difficult to maintain.
So, we have to find a way to avoid such a code appearing in our project.

The benefits and annoyances of asynchronous programming

The JavaScript engine is single-threaded, but with asynchronous programming, the Nodejs that runs on the server side has high performance.
It also has the ability to perform IO operations in parallel, which makes it possible for many child shoes to write a number of callback nesting code.
Make our code look ugly. Of course, this is not the problem of the JS language itself, like the beginning of the written:

There is no multi-layer callback nested in the world, write more people will have.

Using promise to solve the problem of callback hell

What is promise?

Promise is an abstract object. COMMONJS defines the PROMISES/A specification.
If you want to be specific about this: Learn more about what promise is.

Promise mode is in one of the following three states at any time:

Not completed (unfulfilled)
Completed (resolved)
Reject (rejected).
More than 1.5 of the Ajax versions of jquery are based on promise implementations. So we can implement AJAX requests using the following methods:

The code is as follows Copy Code

$.when (
$.ajax (' url '),
$.ajax (' Url2 ')
)
. then (Successcallback,failcallback);
The callback function executes only if 2 Ajax are complete
Note: The $.ajax (' URL ') returns a Promise object

How to implement a promise

Next we're going to implement a promise, and we'll call him deferred (consistent with jquery).

The code is as follows Copy Code

function Deferred () {
This.donecallbacks = [];
This.failcallbacks = [];
}

Deferred.prototype.done = function (CB) {
This.doneCallbacks.push (CB);
return this;
};

Deferred.prototype.fail = function (CB) {
This.failCallbacks.push (CB);
return this;
};

Deferred.prototype.resolve = function () {
var Dcbs = this.donecallbacks;
for (Var i=0,len=dcbs.length;i<len;i++) {
Dcbs[i] ();
}
return this;
}

The realization of analog $.when
function when () {
var aidx = 0, Alen=arguments.length,
DFD = new Deferred ();

function callback () {
Console.log ("[+ ++aidx +] method" has been executed);
if (Aidx = = ALen) {
Dfd.resolve (); Change the execution state of a deferred object
}
}

for (var i=0; i< ALen; i++) {
Arguments[i].done (callback);
}
return DFD;
}

Customizing methods for asynchronous execution
var wait = function (intval) {
var DFD = new Deferred (); Inside the function, create a new deferred object
var tasks = function () {
Console.log ("Time consuming [+intval/1000+] seconds" execution completed!) ");
Dfd.resolve (); Change the execution state of a deferred object
};
SetTimeout (Tasks,intval);
return DFD; Returns the deferred object
};

Call Test
When (5000), Wait (10000). Done (function () {Console.log (' invoke first Done ');}). Done (function () {Console.log (' invoke second Done ');};
Console.log (' over ')

As the code above, the principle is: use deferred to save the callback function and state, and so on, after the asynchronous operation is completed, change the state, triggering the corresponding callback function.

Solve some problems of asynchronous programming callback using Primose method

If you want to use the Priomse method to solve the callback nesting problem that asynchronous programming brings,
So we're going to need to encapsulate all of our functions that contain asynchronous operations,
Encapsulated into promise objects, we can use a similar:

$.when (Promise1,promise2,....). Then (...);
Back to the example of the animation mentioned at the beginning, we can do this like this:

  code is as follows copy code

function Animate (Dis,time) {
    var def = $. Deferred ();
    $ ('. Boll ')
    animate ({
        left:dis+ ' px '
   },time, function () {
        def.resolve (time);
   });
    return def;
}

$ ('. Boll '). On (' click ', Function () {
    $.when (
    Animate ( 50,1000),
    animate (120,100),
    animate (200,500))
   . Done (function (DD,TT,KK) {
        console.log (DD,TT,KK)
    })
});


When the argument must be a Promise object, when (XXX) returns a promise.
So this necessarily increases some of the amount of code we have, but it's worth it for better readability and maintainability.
So promise introduces here, and then there are 2 more articles that will use another 2 ways to solve the callback nesting problems that asynchronous programming brings.

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.