jQuery Deferred源码详解与Promise对比

1 下载量 44 浏览量 更新于2024-09-02 收藏 97KB PDF 举报
本文将深入剖析jQuery中的Deferred源码,这是一种在jQuery 1.8及以后版本中用于处理异步操作的强大工具。Deferred对象借鉴了ES6 Promise的设计理念,通过链式调用避免回调地狱,使得代码更为清晰和可维护。 首先,我们回顾一下Deferred的基本用法。例如,`$.Deferred()`函数创建一个Deferred实例,然后可以使用`.then()`方法来注册成功回调,`.done()`或`.fail()`处理完成或失败的情况。在jQuery 1.8之后,`.then()`返回一个新的受限制的Deferred对象,这意味着原Deferred的状态不会被改变,导致`done`回调中没有值传递。 接下来,让我们详细分析jQuery的Deferred源码。它主要包括以下几个部分: 1. **构造函数**: `jQuery.extend({ Deferred: function(func) {...}`定义了一个构造函数,接受一个可选的函数作为参数。这个构造函数初始化了一个Deferred对象,包含四个关键属性:动作(action,如resolve、reject或notify)、监听器集合(如done、fail或progress)、以及状态(pending、resolved或rejected)。 2. **action-tuple数组**: 这个数组定义了三种主要的操作及其对应的回调机制。`resolve`对应成功完成,`reject`对应失败,而`notify`用于进度更新。每个操作都有一个回调函数,比如`jQuery.Callbacks("oncememory")`,这表示回调只执行一次。 3. **状态**: 初始状态为`"pending"`,表示操作正在进行中。当`resolve`或`reject`方法被调用时,状态会变为`"resolved"`或`"rejected"`,表明操作已结束。 4. **链式调用**: 在`runAsync`示例中,`.then()`方法返回一个新的Deferred,允许在原Promise链中添加新的操作。这使得代码更易于阅读和维护。 5. **`.promise()`方法**: 从jQuery 1.8开始,`.then()`方法实际上返回的是一个新的`deferred.promise()`,这是对原始Deferred的引用。这解释了为什么在`done`回调中打印的是`undefined`,因为`resolve`后,原`done`回调并未关联到新的Promise实例。 理解jQuery的Deferred源码有助于开发者更好地掌握异步编程的模式,以及如何利用Deferred处理复杂的异步操作,提高代码的可读性和可维护性。同时,它也展示了JavaScript设计模式在实际项目中的应用,特别是对于处理回调函数的优雅管理。