jQuery.when()方法是jQuery内部使用回调机制的范例。

// 参数为多个方法,这些方法全部执行完成之后执行回调
when: function( subordinate /* , ..., subordinateN */ ) {
  var i = 0,

  // 将传入的参数切成数组
  resolveValues = core_slice.call( arguments ),
  length = resolveValues.length,

  // 未执行完成的方法 、
  remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

  // 当未执行完成的方法只剩一个时,生成deferred对象
  deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

  //

  updateFunc = function( i, contexts, values ) {
    return function( value ) {
      contexts[ i ] = this;
      values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;

      // 如果所有方法都正在执行
      if( values === progressValues ) {

        // 调用deferred对象的notifyWith方式,实际是就是调用Callback的fireWith方法,该方法会判断是将回调放入回到函数栈还是直接触发
        deferred.notifyWith( contexts, values );

      // 否则,如果全都执行完毕
      } else if ( !( --remaining ) ) {
        deferred.resolveWith( contexts, values );
      }
    };
  },

  progressValues, progressContexts, resolveContexts;

  // 如果参数数量大于1
  if ( length > 1 ) {

    // 新建一个length长度等于参数数量的数组并复制给progressValues
    progressValues = new Array( length );

    // 新建一个length长度等于参数数量的数组并复制给progressContexts
    progressContexts = new Array( length );

    // 新建一个length长度等于参数数量的数组并复制给resolveContexts
    resolveContexts = new Array( length );

    
    for ( ; i < length; i++ ) {

      // 如果存在第i个传入的方法,并且该方法有一个promise属性也是一个方法(说明该方法会返回一个promise对象)
      if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {

        // 监控该方法是否完成,分别调用响应的回调函数
        resolveValues[ i ].promise()

          // 如果完成,则执行updateFunc方法
          .done( updateFunc( i, resolveContexts, resolveValues ) )

          // 如果失败,则直接标记deferred失败
          .fail( deferred.reject )

          // 如果正在执行,也调用updateFunc方法
          .progress( updateFunc( i, progressContexts, progressValues ) );
      } else {

        // 如果不存在第i个方法,remaining减1
        --remaining;
      }
    }
  }

  // 如果已经没有方法未执行完成,调用deferred的resolveWith方法
  if ( !remaining ) {
    deferred.resolveWith( resolveContexts, resolveValues );
  }

  // 返回deferred.promise方法(相当于提供了一个所有方法都执行完成的回调)

  return deferred.promise();
}

jQuery的回调管理机制(三)的更多相关文章

  1. jQuery的回调管理机制(二)

    jQuery.extend({ /*  * deferred对象的一大好处,就是它允许你自由添加多个回调函数. * $.ajax("test.html")   .done(func ...

  2. jQuery的回调管理机制

    // 对option的一个缓存,避免每次都需要createOptions,option是创建Callback对象时的传入的参数// 每个option被存入optionsCache中类似于{memory ...

  3. NameNode元数据的管理机制(三)

    元数据的管理: 第一步:客户端通过DistributedFilesystem 对象中的creat()方法来创建文件,此时,RPC会 通过一个RPC链接协议来调用namenode,并在命名空间中创建一个 ...

  4. 你必须了解的java内存管理机制(三)-垃圾标记

    本文在个人技术博客不同步发布,详情可用力戳 亦可扫描屏幕右侧二维码关注个人公众号,公众号内有个人联系方式,等你来撩... 相关链接(注:文章讲解JVM以Hotspot虚拟机为例,jdk版本为1.8) ...

  5. mybatis深入理解(三)-----MyBatis事务管理机制

    MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面.本文将讲述MyBatis的事务管理的实现机制.首先介绍MyBatis的事务Transaction的接口设计以及其不 ...

  6. ARC内存管理机制详解

    ARC在OC里面个人感觉又是一个高大上的牛词,在前面Objective-C中的内存管理部分提到了ARC内存管理机制,ARC是Automatic Reference Counting---自动引用计数. ...

  7. Linux中断管理 (1)Linux中断管理机制

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

  8. C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?

    C#中??和?分别是什么意思? 在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; ...

  9. Linux中断管理 (1)Linux中断管理机制【转】

    转自:https://www.cnblogs.com/arnoldlu/p/8659981.html 目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机 ...

随机推荐

  1. Centos下查看cpu、磁盘、内存使用情况以及如何清理内存

    核查服务器基本情况 查看内存使用情况 free -m 查看cpu使用情况 top #查看进程运行情况 查看磁盘以及分区情况 df -h 查看网络情况 ifconfig 查看端口使用情况 #1.方法一 ...

  2. 让小区运营再智能一点,EasyRadius正式向WayOs用户提供到期弹出式提示充值页面

    其实一直没向用户提供到期弹出式页面,主要是给VIP群的用户一点优越感,随着这次EasyRadius的更新,海哥就免费向普通easyRadius用户提供这两个模板下载. 有些人会问,什么样的模板.有什么 ...

  3. ubuntu 12.04和Windows 7双系统的安装方法

    ubuntu是一个操作系统,和安卓一样同是linux内核下的子民,所以来这贡献一下,也求JW放出安卓4.0原生正式版,我只想要这个. 前几天发布了ubuntu12.04LTS 版本,兴奋ing. 看到 ...

  4. C# WORD操作实现代码(转载)

    在当前项目开发过程中,客户有根据数据库数据生成WORD文档的需求,在和同事沟通的过程中,找到了两个解决方案 1.先通过程序生成报表样式的HTML页面,然后修改HTML页面的后缀名为DOC. 2.定制W ...

  5. thinkphp3.2 session时间周期无效

    Thinkphp3.2 session周期时间默认是无效的 方法一: 这种方法使用session非常麻烦 1.配置'SESSION_AUTO_START' =>false,2.控制器方法sess ...

  6. 组合模式(Composite Pattern) ------------结构型模式

    组合模式使用面向对象的思想来实现树形结构的处理和构件,描述了如何将容器对象和叶子对象进行递归组合,实现简单,灵活性好. 组合模式(Composite Pattern):组合多个对象形成树形结构以表示具 ...

  7. 近5年常考Java面试题及答案整理(一)

    下列面试题都是在网上收集的,本人抱着学习的态度找了下参考答案,有不足的地方还请指正. 1.面向对象的特征有哪些方面? 抽象:将同类对象的共同特征提取出来构造类. 继承:基于基类创建新类. 封装:将数据 ...

  8. Lua 中 number 转换各种进制,以及string串转number

    原文地址:http://blog.csdn.net/david_dai_1108/article/details/71699449 --region : NumConvert.lua --Date : ...

  9. wingIDE设置支持中文注释

    用wingIDE快2年了,实在是受不了不支持中文,每次中文都报错,一个小逗号也要查很久,别说中文注释了,在网上找解决办法,原来这么简单! 下面,把破解放大和支持中文支持的方法备份下来,以便以后查看. ...

  10. Ajax请求全局配置

    摘要: jQuery已经成为项目中最常见的js库,也是前端开发最喜欢使用的库.下面是在项目中封装了jQuery的Ajax,分享给大家. 代码: // ajax 请求参数 var ajaxSetting ...