Comparative Analysis of .then() vs .done() Methods in jQuery Deferred and Promises

Nov 21, 2025 · Programming · 10 views · 7.8

Keywords: jQuery | Deferred | Promise | .then() | .done() | Asynchronous Programming | Chaining

Abstract: This article provides an in-depth exploration of the core differences between the .then() and .done() methods in jQuery Deferred objects. Through version evolution analysis, it details the behavioral changes of the .then() method before and after jQuery 1.8, transitioning from simple syntactic sugar to a Promise-returning method with filtering and chaining capabilities. The article combines code examples to demonstrate the multi-callback feature of .done(), the chain propagation mechanism of .then(), and practical application scenarios in asynchronous operation orchestration, offering clear usage guidance for developers.

Introduction

In jQuery's asynchronous programming model, Deferred objects and the Promise pattern provide robust support for handling asynchronous operations. Among these, the .then() and .done() methods are commonly used for attaching callbacks. While superficially both handle successfully completed operations, they exhibit significant differences in underlying mechanisms and usage scenarios. This article systematically analyzes the core distinctions between these two methods from three perspectives: historical version evolution, functional特性对比, and practical application examples.

Basic Concepts and Version Evolution

In jQuery, a Deferred object represents an operation that has not yet completed but will do so in the future, with states including resolved, rejected, and pending. A Promise is a read-only view of a Deferred, used to attach callbacks without altering its state.

Prior to jQuery 1.8, the .then() method was essentially syntactic sugar, functionally equivalent to consecutive calls to .done() and .fail(). Specifically:

promise.then(doneCallback, failCallback)
// was equivalent to
promise.done(doneCallback).fail(failCallback)

This design allowed developers to specify both success and failure callbacks in a more concise manner. However, starting with jQuery 1.8, the behavior of .then() underwent a fundamental change. It is no longer mere syntactic sugar but became an alias for the .pipe() method and returns a new Promise object. This change endowed .then() with enhanced capabilities, including value filtering and chain operations.

Functional特性对比 Analysis

Core特性 of .done() Method

The .done() method is specifically used to attach callback functions that execute when the Deferred object is resolved. Its core特性 include:

Modern Implementation of .then() Method

Since jQuery 1.8, the .then() method exhibits the following important特性:

Empirical Analysis of Chaining Behavior Differences

Chaining behavior is one of the most notable differences between .then() and .done(). The following comparative examples clearly illustrate this disparity:

// Example of chain propagation with .then()
var promise = $.Deferred().resolve("abc");
promise.then(function(x) {
    console.log(x); // Output: "abc"
    return 123;
}).then(function(x) {
    console.log(x); // Output: 123
}).then(function(x) {
    console.log(x); // Output: undefined
});
// Example of no propagation with .done()
var promise = $.Deferred().resolve("abc");
promise.done(function(x) {
    console.log(x); // Output: "abc"
    return 123;
}).done(function(x) {
    console.log(x); // Output: "abc"
}).done(function(x) {
    console.log(x); // Output: "abc"
});

From the output, it is evident that .then() forms a genuine call chain, where the return value of each callback becomes the input parameter for the next. In contrast, all callbacks of .done() receive the same original resolved value, and return values are ignored.

Practical Applications in Asynchronous Operation Orchestration

The chaining特性 of .then() make it excel in orchestrating complex asynchronous operations, particularly in scenarios requiring sequential or parallel processing of multiple asynchronous tasks.

Sequential Asynchronous Operations

The following example demonstrates how to use .then() to implement sequential HTTP requests:

function sequentialRequests() {
    return $.get('/api/first').then(function(result1) {
        console.log('First request completed:', result1);
        return $.get('/api/second?value=' + result1);
    }).then(function(result2) {
        console.log('Second request completed:', result2);
        return $.get('/api/third?value=' + result2);
    }).then(function(result3) {
        console.log('All sequential requests completed:', result3);
        return result3;
    });
}

Parallel Asynchronous Operations

For scenarios requiring parallel execution and result merging, .then() can also handle it elegantly:

function parallelRequests() {
    var promise = $.Deferred().resolve("start");
    
    return promise.then(function() {
        var request1 = $.get('/api/data1').then(function(result) {
            console.log('Request 1 completed:', result);
            return result;
        });
        
        var request2 = $.get('/api/data2').then(function(result) {
            console.log('Request 2 completed:', result);
            return result;
        });
        
        // Use $.when to wait for all parallel requests to complete
        return $.when(request1, request2).then(function(result1, result2) {
            return {
                data1: result1,
                data2: result2
            };
        });
    }).then(function(combinedResult) {
        console.log('All parallel requests completed:', combinedResult);
        return combinedResult;
    });
}

Association with Ajax-Specific Methods

It is important to note that .success() and .error() are not general methods of Deferred objects but are specific aliases for the jqXHR object (the return value of Ajax requests):

var jqXHR = $.ajax('/api/data');
// The following equivalences hold true
jqXHR.done === jqXHR.success
jqXHR.fail === jqXHR.error

This design allows Ajax calls to use more semantic method names, but these methods do not exist on generic Deferred objects.

Version Compatibility Considerations

When choosing between .then() and .done(), consider the jQuery version used in the project:

Conclusion and Best Practices

Through in-depth analysis of .then() and .done(), the following usage recommendations can be derived:

Understanding the fundamental differences between these two methods aids developers in making more appropriate technical choices when faced with various asynchronous programming needs, leading to more robust and maintainable JavaScript code.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.