• jQuery的回调管理机制(三)


    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();
    }

  • 相关阅读:
    转:Windows 7下安装CentOS双系统
    STL学习总结之<迭代器>
    转:linux静态库与动态库
    指向类成员和成员函数的指针
    STL学习总结之<仿函数>
    转:Linux Crontab 定时任务 命令详解
    转: 解决 Redhat 出现”This system is not registered with RHN”更新
    IOS 判断设备屏幕尺寸、分辨率
    IOS 文件管理共通函数整理
    IOS 编译ffmpeg For SDK6.1,模拟器、armv7、armv7s均可使用
  • 原文地址:https://www.cnblogs.com/charling/p/3458627.html
Copyright © 2020-2023  润新知