jquery中的 deferred之 deferred对象 (一)

案例:

var def=$.Deferred();
console.log(def);//答案见 图1

图1:

deferred就是一个有这些方法的对象。

看源码分析:

Deferred: function( func ) {
        var tuples = [
                // action, add listener, listener list, final state
                [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
                [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
                [ "notify", "progress", jQuery.Callbacks("memory") ]
            ],
            state = "pending",
            promise = {
                state: function() {
                    return state;
                },
                always: function() {
                    deferred.done( arguments ).fail( arguments );
                    return this;
                },
                then: function( /* fnDone, fnFail, fnProgress */ ) {
                    var fns = arguments;
                    return jQuery.Deferred(function (newDefer) { //20170620 huanhua 当调用 jQuery.Deferred(参数)  参数不为空的时候,参数必须是 包含 $.Deferred()对象参数的函数
                                                                  //if ( func ) { func.call( deferred, deferred );} 详见下面这段代码。
                        jQuery.each(tuples, function (i, tuple) {
                            var action = tuple[ 0 ],
                                fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
                            // deferred[ done | fail | progress ] for forwarding actions to newDefer
                            deferred[ tuple[1] ](function() {
                                var returned = fn && fn.apply(this, arguments);
                                //20170620 huanhua 如果then方法传递的参数 [fnDone, fnFail, fnProgress],其中的函数如果返回的是 Defferred对象。
                                if (returned && jQuery.isFunction(returned.promise)) {
                                    //20170620 huanhua 此时注册的 done/fail/progess 就是传入的 Defferred对象已经注册好了的对象
                                    //20170624 huahua returned是一个 deferred,在 fn 里面,必须要调用 deferred.resolve/deferred.reject/deferred.notify
                                    //否则不会 触发 newDefer.resolve/newDefer.reject/newDefer.notify
                                    returned.promise()
                                        .done( newDefer.resolve )
                                        .fail( newDefer.reject )
                                        .progress( newDefer.notify );
                                } else {
                                    newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
                                }
                            });
                        });
                        fns = null;
                    }).promise();
                },
                // Get a promise for this deferred
                // If obj is provided, the promise aspect is added to the object
                promise: function (obj) {
                    return obj != null ? jQuery.extend( obj, promise ) : promise;
                }
            },
            deferred = {};

        // Keep pipe for back-compat
        promise.pipe = promise.then;

        // Add list-specific methods

        jQuery.each( tuples, function( i, tuple ) {
            var list = tuple[2], //20170619 huanhua jQuery.Callbacks("once memory") | jQuery.Callbacks("once memory") | jQuery.Callbacks("memory")
                stateString = tuple[3]; //20170619 huanhua "resolved" | "rejected" | undefined

            // promise[ done | fail | progress ] = list.add
            //20170619 huanhua  promise.done/promise.fail/promise.progess = jQuery.Callbacks(参数).add
            promise[ tuple[1] ] = list.add;

            // Handle state
            //20170619 huanhua stateString取值 "resolved" | "rejected" | undefined
            if ( stateString ) {
                list.add(function() {
                    // state = [ resolved | rejected ]
                    state = stateString;

                    // [ reject_list | resolve_list ].disable; progress_list.lock
                    //20170619 huanhua 0 ^ 1=1  1 ^ 1 = 0  2 ^ 1 = 3
                    //20170619 huanhua stateString取值 "resolved" | "rejected" | undefined,所以 i 只能取值 0或者 1
                    //20170620 huanhua 解释 tuples[i ^ 1][2].disable, tuples[2][2].lock
                    //当 i=0 时,stateString="resolved",已经执行完,tuples[i ^ 1][2]=tuples[1][2],就是 fail的 disable,tuples[2][2] 就是 progess的 lock
                    //当 i=1 时,stateString="rejected",已经拒绝了,tuples[i ^ 1][2]=tuples[0][2],就是 done的 disable,tuples[2][2] 就是 progess的 lock
                }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
            }

            // deferred[ resolve | reject | notify ]
            //20170619 huanhua deferred.resolve()/deferred.reject()/deferred.notify()
            //最终调用的都是  deferred.resolveWith()/deferred.rejectWith()/deferred.notifyWith()
            deferred[tuple[0]] = function () {
                deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
                return this;
            };
            //20170619 huanhua deferred.resolveWith()/deferred.rejectWith()/deferred.notifyWith()最终调用的就是 callBacks的 fire()
            deferred[ tuple[0] + "With" ] = list.fireWith;
        });

        // Make the deferred a promise
        // 20170619 huanhua 把promise的属性全部扩展到 defferred对象上
        promise.promise( deferred );

        // Call given func if any
        if ( func ) {
            func.call( deferred, deferred );
        }
        // All done!
        return deferred;
    },
时间: 2024-10-10 06:54:34

jquery中的 deferred之 deferred对象 (一)的相关文章

使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 页面事件与 deferred

在系列的上一篇文章<使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 事件详解>中,Kayo 介绍了除页面事件外的其他 jQuery Mobile 事件,而页面事件由于事件数较多,并且涉及 jQuery 中一个比较复杂的对象 deferred ,因此在本文中单独说明.jQuery Mobile 页面事件使用分为页面加载事件 (Page load events),页面跳转事件 (Page change events),页面显示/隐藏事件 (

jquery中each遍历对象和数组

jquery中each可用于遍历对象和数组,如需退出each循环可使回调函数返回false 1.$().each(),回调函数拥有两个参数: 第一个为对象的成员或数组的索引,第二个为对应变量或内容.如需退出each循环可使回调函数返回false 例子: 现有如下两个select 计划类别: <select id="PLANTYPE"> <option value="0">-所有-</option> <option value

从零开始学习jQuery (六) jquery中的AJAX使用

本篇文章讲解如何使用jQuery方便快捷的实现Ajax功能.统一所有开发人员使用Ajax的方式. 一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些许秘籍. 本篇文章讲解如何使用jQuery方便快捷的实现Ajax功能.统一所有开发人员使用Ajax的方式. 二.前言 Ajax让用户页面丰富起来, 增强了用户体验. 使用Ajax是所有Web开发的必修课. 虽然Ajax技术并不复杂, 但是实现方式还是会因为每个

jQuery入门(4)jQuery中的Ajax应用

jQuery入门(1)jQuery中万能的选择器 jQuery入门(2)使用jQuery操作元素的属性与样式 jQuery入门(3)事件与事件对象 jQuery入门(4)jQuery中的Ajax应用 一.原始Ajax与jQuery中的Ajax 首先通过实例, 来看一下jQuery实现Ajax有多简单. 下面是一个使用原始Ajax的示例: 01 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "

jQuery中的deferred对象的使用(一)

在jquery1.5之后的版本中,加入了一个deferred对象,也就是延迟对象,用来处理未来某一时间点发生的回调函数.同时,还改写了ajax方法,现在的ajax方法返回的是一个deferred对象. 那就来看看deferred对象的用法. 1.ajax的链式回调 // ajax方法返回的是一个deferred对象,可以直接使用链式写法 $.ajax('test.json').done(function(resp){ // done 相当于success回调,其中默认的参数为success回调的

jQuery中异步操作对象Deferred

以下介绍一下jQuery中Deferred对象的使用: 1. 通过$.Deferred生成一个deferredObj对象; 2. deferredObj.done()指定操作成功时的回调函数; 3. deferredObj.fail()指定操作失败时的回调函数; 4. deferredObj.promise()没有参数时,作用为保持deferred对象的运行状态不变:接受参数时,作用为在参数对象上部署deferred接口; 5. deferredObj.resolve()手动改变deferred

jQuery中deferred对象的使用(二)

接上一回的内容,漏了一个always()方法,参数也是回调函数,与done和fail不同的是,无论任何情况都执行always方法中的回调. deferred对象的使用(二) deferred对象不光可以用在jquery的ajax方法中,他提供了一系列的接口,使它的通用型大大提高. 比如有这样一个耗时比较久的方法 function a(){ function b(){ alert('start'); } setTimeout(b, 3000); } 如果要在这个方法之后执行某个回调,就不能用$.w

jQuery中的$.Deferred、$.when异步操作

前言 网页中常常会出现一些耗时比较长的操作,如ajax请求服务器数据,这些操作都不能立即得到结果.如果我们需要在这些操作执行完后来进行另外的操作,我们就需要将这些操作放在回调函数中,$.Deferred就是jQuery用来处理回调操作的.jQuery中的$.Deferred对$.Callbacks很有依赖,看看$.Callbacks执行回调. 1 var callbacks = $.Callbacks(); 2 setTimeout(function(){ 3 console.log(1); /

深入理解jQuery中的Deferred

引入 1  在开发的过程中,我们经常遇到某些耗时很长的javascript操作,并且伴随着大量的异步. 2  比如我们有一个ajax的操作,这个ajax从发出请求到接收响应需要5秒,在这5秒内我们可以运行其他代码段,当响应到达后,我们需要判断响应的结果(无非就是成功或者失败),并根据不同的结果  添加回调函数. 3  为了有效的简洁的添加回调函数jQuery引入了Callbacks. 4  而为了方便的 根据不同的结果(或者根据各种跟结果有关的逻辑,比如不管是成功或者失败) 添加回调函数,jQu