zoukankan      html  css  js  c++  java
  • jQuery中的$.Deferred、$.when异步操作

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

      $.Deferred来实现上面的操作

    1     var deferred = $.Deferred();
    2     setTimeout(function(){
    3         console.log(1); // 1
    4         deferred.resolve();// 2
    5     }, 1000);
    6     deferred.done(function(){
    7         console.log(2);
    8     });
    $.Deferred的三队抽象
    1、resolve-》done-》$.Callbacks('once memory')-》成功-》只触发一次
    2、reject-》fail-》$.Callbacks('once memory')-》失败-》只触发一次
    3、notify-》progress-》$.Callbacks('memory')-》通知-》不断触发直到resolve或reject
     1     var deferred = $.Deferred();
     2     setTimeout(function(){
     3         //deferred.resolve(); // success
     4         deferred.reject(); // error
     5         //deferred.notify(); // progressing
     6     }, 1000);
     7     deferred.done(function(){
     8         console.log('success');
     9     }).fail(function(){
    10         console.log('error');
    11     }).progress(function(){
    12         console.log('progressing');
    13     });

    下面是一个比较有意思的用法:memory的记忆功能。

     1     var deferred = $.Deferred();
     2     setTimeout(function(){
     3         deferred.resolve();// 1
     4     }, 100);
     5     deferred.done(function(){
     6        console.log(1);
     7     });
     8     $('#btn').on('click', function () {
     9         deferred.done(function(){
    10             console.log(2); // 2...只要单击一次按钮就会触发一次
    11         });
    12     });
    deferred和promise
      $.Deferred会有两个延迟对象,分别是deferred和promise。deferred包含有所有的方法,而promise不包含改变延迟对象状态的三个方法resolve、reject、notify。这样做的好处就是在某些时候对外不提供改变对象状态的方法,以免延迟对象的状态混乱。
     1     function fn(){
     2         var deferred = $.Deferred();
     3         setTimeout(function(){
     4             deferred.resolve();// 不会触发,状态在外部被修改了。
     5         });
     6         return deferred;
     7     }
     8     var newDeferred = fn();
     9     newDeferred.done(function(){
    10         console.log('success');
    11     }).fail(function(){
    12         console.log('error');
    13     });
    14     newDeferred.reject(); // error
     1     function fn(){
     2         var deferred = $.Deferred();
     3         setTimeout(function(){
     4             deferred.resolve();// success
     5         });
     6         return deferred.promise();
     7     }
     8     var newDeferred = fn();
     9     newDeferred.done(function(){
    10         console.log('success');
    11     }).fail(function(){
    12         console.log('error');
    13     });
    14     newDeferred.reject(); // 报错 reject方法不存在
    其他方法介绍
    1、state:返回延迟对象的状态
      pending:创建对象时的状态
      resolved:回调成功-会禁用失败和notify的回调
      rejected:回调失败-会禁用成功和notify的回调
    2、always:不管成功或失败都会触发
    3、then:传递三个方法分别处理三个操作
    4、pipe:延迟对象过滤器?
    resolve、done、reject、fail、notify、progress
    $.when
    1、$.when(deferred):一个延迟对象。
    2、$.when(deferred, deferred,...):多有的延迟对象都调用了resolve()时才执行done;只要有一个延迟对象调用了reject()就会执行fail()。
     1     function fn1(){
     2         var deferred = $.Deferred();
     3         setTimeout(function(){
     4             deferred.resolve();
     5         }, 1000);
     6         return deferred.promise();
     7     }
     8     function fn2(){
     9         var deferred = $.Deferred();
    10         setTimeout(function(){
    11             deferred.resolve();
    12         }, 1000);
    13         return deferred.promise();
    14     }
    15     $.when(fn1(), fn2()).done(function(){
    16         console.log('success'); // 都resolve() success
    17     }).fail(function(){
    18         console.log('error'); // 有一个reject() error
    19     });
     3、如果参数不是延迟对象就会跳过该参数并代表成功,如果参数都不是延迟对象,也会成功,会执行done。
     1     function fn1(){
     2         var deferred = $.Deferred();
     3         setTimeout(function(){
     4             deferred.resolve();
     5         }, 1000);
     6         return deferred.promise();
     7     }
     8     $.when(fn1(), 123).done(function(){
     9         console.log('success'); // fn1()->resolve() success
    10     }).fail(function(){
    11         console.log('error'); // fn1()->reject() error
    12     });

    NOTE:成功或失败的回调函数的参数对应when中的参数,如果参数是延迟对象回调函数得到undefined,不是延迟对象得到参数值。

     1     function fn1(){
     2         var deferred = $.Deferred();
     3         setTimeout(function(){
     4             deferred.resolve();
     5         }, 1000);
     6         return deferred.promise();
     7     }
     8     $.when(fn1(), 123).done(function(arg1, arg2){
     9         console.log(arg1);// undefined
    10         console.log(arg2);//123
    11         console.log('success'); // fn1()->resolve() success
    12     }).fail(function(){
    13         console.log('error'); // fn1()->reject() error
    14     });
  • 相关阅读:
    office2013 激活方式
    c# DataGridView绑定DataTable对象之后总会多一行
    oracle函数验证时间格式并返回
    Linux虚拟机与外面系统ping不通,或者连不上网
    恢复oracle中误删除drop掉的表
    WebService 检测到有潜在危险的 Request.Form 值
    mybatis标签之——关联映射
    word使用宏定义来统一设置图片大小
    mybatis常用标签
    mybatis标签之——<trim>
  • 原文地址:https://www.cnblogs.com/tyxloveyfq/p/4309929.html
Copyright © 2011-2022 走看看