Deferred registers callback functions into a queue, manages them uniformly, and can call these functions synchronously or asynchronously.
jQuery.Deferred() is used to construct a Deferred object. This object has state values, there are three types: Rejected, Resolved and initial state. Resolved means that the operation was successfully completed, while Rejected means that an error occurred and the call failed. The main members of the Deferred object are as follows:
done(callback): Register a callback function, which is called when the status is resolved. * fail(callback): Register a callback function, which will be called when the status is rejected. * always(callback): Register a callback function, which will be called whether it is resolved or rejected. * then(successCallback, failureCallback): Pass in the success and failure callback functions at the same time. * pipe(successFilter, failureFilter): Call the function specified by pipe before calling the success and failure callback functions. It is regarded as a pipeline mechanism that intercepts function calls. * resolve(args): Set the status to Resolved. * reject(args): Set the status to Rejected. * promise(): Returns an incomplete Deferred interface without resolve and reject. That is, the state of the Deferred object cannot be modified. Can be thought of as a read-only view. This is to prevent external functions from triggering the callback function early. For example, $.ajax no longer returns XMLHttpRequest after version 1.5, but instead returns an object that encapsulates the XMLHttpRequest and Deferred object interfaces. The Deferred part is obtained by promise(), which prevents external functions from calling resolve and reject, and prevents the callback function from being triggered before ajax is completed. Reserve the calling permission of these two functions to ajax internally.
The code for this module starts at line 939, immediately following the declaration of the jQuery object. It can also be regarded as a basic core code. It is also one of the biggest changes in version 1.5.
In fact, the code logic of Resolve and Reject is the same, but the corresponding states are different. For code reuse, a Deferred is first implemented internally, and then two Deferreds are new inside the real Deferred, one as Resolve and the other as Reject.
_Deferred object maintains a function array (callback list) internally. The job of Done(f1, f2...) is to push these callbacks to this queue in sequence and save them. And resolveWith (resolve with parameters) and resolve call this callback function in sequence.
In Done, it is necessary to determine whether the event has been completed. If the event has been completed when the callback is added to the chain, the callback needs to be executed immediately. This feature is the reason why callback no longer needs to be written together with the declaration of triggering asynchronous events. For example, it turns out that $.post("...", function(data) { ... }) must be written. This success callback must be written here, but now it can be written: