您当前的位置: 首页 >  jquery

wespten

暂无认证

  • 0浏览

    0关注

    899博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

深入学习jquery源码之Deferred对象与holdReady()

wespten 发布时间:2019-08-28 10:16:28 ,浏览量:0

深入学习jquery源码之Deferred对象与holdReady()

jQuery的Deferred对象也有resolve、reject、then方法,还有done、fail、always......方法。jQuery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。


    var defer = $.Deferred();
    console.log(defer);

一直用的jquery的ajax

          $.ajax({
                  url: 'abc.com',
                  type: 'post',
                  data: { abc:1 },
                  success: function (data) {
                      if (!data.success) {
                          alert(data.message);
                      } else {
  
                     }
                 }
             });

Deferred对象的reject方法会回调所有的 fail 方法,resolve 会回调所有的 done方法

   $.ajax({
       url: 'abc.com/index',
       type: 'post',
       data: { abc:1 },
  }).done(function(data) {
      if (!data.success) {
           alert(data.message);    
       } else {
       }
  }).fail(function() {
      alert('请稍后重试');
  });
  function test(txt) {
      var dtd = $.Deferred();
      if (!txt.trim()) {
          dtd.reject({ msg: '不能为空' });
      } else if (!reg.test(txt)) {
          dtd.reject({ msg: '含有非法字符' });
      } else if (this.tags.indexOf(txt)>=0) {
          dtd.reject({ msg: '已重复' });
      }
   dtd.resolve();
     return dtd.promise();
 }
 
 调用:
     test('xxx')
     .done(function(data){  
      //xxxxxx
     })
     .fail(function(data){ 
       //xxxx
     })

Deferred对象的实例defer通过resolve方法把参数 “异步请求成功之后返回的数据” 传回到then方法中进行接收,,打印。

    function runAsync(){
        var defer = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            defer.resolve('异步请求成功之后返回的数据');
        }, 1000);
        return defer;
    }
    runAsync().then(function(data){
        console.log(data)
    });

和ES6的Promise区别

    function runAsync(){
        var p = new Promise(function(resolve, reject){
           
            setTimeout(function(){
                console.log('执行完成');
                resolve('异步请求成功之后返回的数据');
            }, 1000);
        });
        return p;            
    }

    runAsync().then(function(data){
        console.log(data);
    });

1、创建Deferred对象的时候没有传参;而创建Promise对象的时候,传了参数(传了一个匿名函数,函数也有两个参数:resolve、reject);

2、Deferred对象直接调用了resolve方法;而Promise对象则是在内部调用的resolve方法;

说明:Deferred对象本身就有resolve方法,而Promise对象是在构造器中通过执行resolve方法,给Promise对象赋上了执行结果的状态。

这样就有一个弊端:因为Deferred对象自带resolve方法,拿到Deferred对象之后,就可以随时调用resolve方法,其状态可以进行手动干预了

直接在外部直接给Deferred设置了状态,打印“在外部结束”,1s后打印“执行完成”,不会打印“异步请求成功之后返回的数据”了。

显然,这不好。我发个异步请求,还没收到数据就让人在外部给我结束了。。。。。。。

    function runAsync(){
        var defer = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            defer.resolve('异步请求成功之后返回的数据');
        }, 1000);
        return defer;
    }
   var der = runAsync();
   der.then(function(data){
        console.log(data)
   });
   der.resolve('在外部结束'); 

Deferred对象上有一个promise方法,是一个受限的Deferred对象

所谓受限的Deferred对象,就是没有resolve和reject方法的Deferred对象。这样就无法在外边改变Deferred对象的状态了。

    function runAsync(){
        var def = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            def.resolve('请求成功之后返回的数据');
        }, 2000);
        return def.promise(); //就在这里调用
    }

Deferred对象的then方法和done、fail语法糖

我们知道,在ES6的Promise规范中,then方法接受两个参数,分别是执行完成和执行失败的回调,而jquery中进行了增强,还可以接受第三个参数,就是在pending状态时的回调,如下:

deferred.then( doneFilter [, failFilter ] [, progressFilter ] )

Deferred对象的then方法也是可以进行链式操作的。

    function runAsync(){
        var def = $.Deferred();
        //做一些异步操作
        setTimeout(function(){
              var num = Math.ceil(Math.random()*10); //生成1-10的随机数
               if(num 1 ? slice.call(arguments) : value;
                        if (values === progressValues) {
                            deferred.notifyWith(contexts, values);

                        } else if (!(--remaining)) {
                            deferred.resolveWith(contexts, values);
                        }
                    };
                },

                progressValues, progressContexts, resolveContexts;

            // add listeners to Deferred subordinates; treat others as resolved
            if (length > 1) {
                progressValues = new Array(length);
                progressContexts = new Array(length);
                resolveContexts = new Array(length);
                for (; i < length; i++) {
                    if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
                        resolveValues[i].promise()
                            .done(updateFunc(i, resolveContexts, resolveValues))
                            .fail(deferred.reject)
                            .progress(updateFunc(i, progressContexts, progressValues));
                    } else {
                        --remaining;
                    }
                }
            }

            // if we're not waiting on anything, resolve the master
            if (!remaining) {
                deferred.resolveWith(resolveContexts, resolveValues);
            }

            return deferred.promise();
        }
    });

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

关注
打赏
1665965058
查看更多评论
立即登录/注册

微信扫码登录

0.1209s