Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining multiple done() callbacks to the same deferred promise

Tags:

jquery

promise

In short, I would like to have one general callback that always fires in case of a successful ajax call, followed by separate callback functionality depending on where the method is invoked.

This seems to work. My question is if this is a correct use of the promise object and if it's safe to assume that multiple promise callbacks of the same type always stack sequentially?

var dfd = $.Deferred(),
    promise = dfd.promise();

promise.done(function(){
    console.log(1);
}).done(function(){
    console.log(2);
});

dfd.resolve();

http://jsfiddle.net/4ax4nxbh/

like image 344
Johan Avatar asked Oct 23 '14 14:10

Johan


People also ask

Are callbacks a good solution for deferred code execution?

Theoretically callbacks are a great solution for deferred code execution. Unfortunately, real use encourages deep callback nesting to handle nested events (async events that result from another async event) Obviously you don't need callbacks for something like string manipulation.

When to use a deep callback chain?

Callbacks are ok when you need to load multiple things and don't care about the order they're handled, but they're not great when you need to write ordered, sequential code. In most cases, people used deep callback chains as artificially sequential code.

What is a callback?

Let’s return to the problem mentioned in the chapter Introduction: callbacks: we have a sequence of asynchronous tasks to be performed one after another — for instance, loading scripts. How can we code it well? Promises provide a couple of recipes to do that. In this chapter we cover promise chaining.

How do you pass a callback function to a promise object?

As you can see, there is no need to pass the callback function in the argument, but instead the caller returns the Promise object and sets the callback function from it after receiving the Promise object. Even if there are multiple calls, you only need to return the Promise object one after another.


1 Answers

It's a correct and documented use of the deferred object in jQuery. The documentation clearly states:

Callbacks are executed in the order they were added.

It works differently in other promise libraries and generally .then is preferred to .done anyway (explained later in the answer). However given you're using jQuery promises it'll stack just fine sequentially if they're synchronous.

So the direct answer to your question is yes.

However, you can also do this with asynchronous code and have it chain better with .then:

promise.then(function(){
    console.log(1);
}).then(function(){
    console.log(2);
}).then(function(){
    return $.get(...);
}).then(function(){
    console.log(3); // this always executes after the $.get finishes.
});

Basically, done adds a handler and returns the same promise and .then returns a new promise chained from the last one. In general I'd only use .done to terminate chains and if you want to keep the return value (the argument of the function(){)

like image 126
Benjamin Gruenbaum Avatar answered Nov 06 '22 06:11

Benjamin Gruenbaum