Misc Deferred Then
## jQuery deferred.then() Method
The `deferred.then()` method is a utility in jQuery used to attach handlers to be called when a Deferred object is resolved, rejected, or still in progress.
This method provides a powerful way to filter the outcomes of asynchronous operations and chain multiple promises together.
---
## Introduction
In asynchronous programming, managing success, failure, and progress states is crucial. The `deferred.then()` method allows you to register callbacks for all three states in a single, clean method call.
### Key Features:
1. **Null Arguments:** Any of the arguments can be `null` if you do not wish to handle that specific state. Alternatively, you can use `.done()`, `.fail()`, or `.progress()` to set up single-state callbacks.
2. **Promise Chaining & Filtering (jQuery 1.8+):** Since jQuery 1.8, `deferred.then()` returns a new Promise. This new Promise can filter the status and values of the original Deferred object through its return value, replacing the now-deprecated `deferred.pipe()` method.
3. **Execution Order:** Callbacks are executed in the order they are added. Because `deferred.then()` returns a Promise, you can chain multiple `.then()` calls sequentially.
---
## Syntax
Depending on your jQuery version and use case, `deferred.then()` can be used in two ways:
### Syntax 1: Filtering (jQuery 1.8+)
Returns a new Promise that filters the resolved/rejected values.
```javascript
deferred.then( doneFilter [, failFilter ] [, progressFilter ] )
```
### Syntax 2: Callbacks (Pre-jQuery 1.8)
Attaches callbacks directly to the Deferred object.
```javascript
deferred.then( doneCallbacks, failCallbacks [, progressCallbacks ] )
```
### Parameter Description
| Parameter | Type | Description |
| :--- | :--- | :--- |
| `doneFilter` / `doneCallbacks` | `Function` / `Array` | **Optional.** A function (or array of functions) called when the Deferred object is resolved. |
| `failFilter` / `failCallbacks` | `Function` / `Array` | **Optional.** A function (or array of functions) called when the Deferred object is rejected. |
| `progressFilter` / `progressCallbacks` | `Function` / `Array` | **Optional.** A function (or array of functions) called when the Deferred object generates progress notifications. |
---
## Code Examples
### Example 1: Basic Usage with AJAX
This example demonstrates how to handle both success and failure states of an AJAX request using `.then()`.
```javascript
$(function () {
// Perform an AJAX GET request
$.get("test.php").then(
function(data) {
alert("$.get Succeeded! Data: " + data);
},
function() {
alert("$.get Failed!");
}
);
});
```
### Example 2: Filtering Resolved Values
You can use `deferred.then()` to pre-process or filter the resolved value before passing it down the promise chain.
```javascript
// Create a Deferred object
var defer = $.Deferred();
// Filter the resolved value
var filtered = defer.then(function(value) {
return value * 2; // Multiply the resolved value by 2
});
// Resolve the original Deferred
defer.resolve(5);
// The filtered promise receives the modified value
filtered.done(function(value) {
console.log(value); // Outputs: 10
});
```
### Example 3: Filtering Rejected Values
Similarly, you can intercept and filter rejected values or convert a rejection into a resolved state.
```javascript
var defer = $.Deferred();
var filtered = defer.then(null, function(errorMsg) {
return "Error intercepted: " + errorMsg;
});
defer.reject("Database connection failed");
filtered.fail(function(value) {
console.log(value); // Outputs: "Error intercepted: Database connection failed"
});
```
### Example 4: Chaining Asynchronous Tasks
Because `.then()` returns a Promise, you can chain sequential asynchronous operations.
```javascript
$.get("user-profile.json")
.then(function(user) {
// Return a new AJAX promise based on the first response
return $.get("user-posts.php?id=" + user.id);
})
.then(
function(posts) {
console.log("User posts loaded successfully:", posts);
},
function() {
console.log("An error occurred during the process.");
}
);
```
---
## Considerations
* **Deprecation of `deferred.pipe()`:** Since jQuery 1.8, `deferred.then()` has fully replaced `deferred.pipe()`. You should always use `.then()` for filtering and chaining in modern jQuery applications.
* **State Propagation:** If a filter function returns a value, the chained promise is resolved with that value. If the filter function returns another Promise/Deferred, the chained promise will wait for it to resolve or reject.
* **Error Handling:** If a filter function throws an error, the returned promise will be rejected with the thrown error.
YouTip