zoukankan      html  css  js  c++  java
  • jQuery deferred 使用心得

    因为项目的原因,我接触到了jQuery deferred 的这个神奇的工具,下面我用几个例子,与大家分享我的感悟。

    我们有5个很耗时的函数 分别为fA、fB、fC、fD、fE  我们的需求是fA和fB同时执行,fA和fB都执行完了,就同时执行fC 和fD ,其中fC和fD只要有一个执行完了,就可以执行fE了。

    先完成第一步,写5个函数,并加入deferred

     1 function fA(){
     2         var dtd = $.Deferred();
     3         console.log('fa Start');
     4         setTimeout(function(){
     5             console.log('fa End');
     6             dtd.resolve();
     7         }, 2000);
     8         return dtd.promise();
     9     };
    10 
    11     function fB(){
    12         var dtd = $.Deferred();
    13         console.log('fb Start');
    14         setTimeout(function(){
    15             console.log('fb End');
    16             dtd.resolve();
    17             
    18         }, 3000);
    19         return dtd.promise();
    20     };
    21 
    22     /***    fC fD fE 省略  ***/

    第二步, fA和fB都执行完了,然后XXX

    先给出我的做法,我们需要用到$.when()这个函数  ,先看效果

    1     $.when(fA(), fB()).done(function(){
    2         console.log('when fA, fB is solved');
    3     });

    打开控制台:

    1 fa Start
    2 fb Start
    3 fa End
    4 fb End
    5 when fA, fB is solved

    有个问题: $.when()是什么

    $.when() ,给出API文档的地址  http://www.css88.com/jqapi-1.9/jQuery.when/

    $.when() 就是接受一个或多个deferred(延迟)对象作为参数, 返回一个deferred(延迟)对象,参数中的deferred对象的状态都变成resolve。就将返回值的状态置为resolve。简单来说,就是坚挺多个deferred回调,都成功,就调用成功的回调(dtd.done())我的理解就是一个deferred的异步‘与门’开关。

    延伸一下,我们能自己实现一下$.when()吗? 按照刚刚的分析我试了一下,如下:

     1 $.extend({
     2     "myWhen": function(){
     3         var args = arguments;
     4         var dtd = $.Deferred();
     5         var argLen = args.length;
     6         var solveCount = 0;
     7 
     8         var argSolve = function(){
     9             if(solveCount >= (argLen - 1)){
    10                 dtd.resolve();
    11             }else{
    12                 solveCount++;
    13             }
    14         }
    15 
    16         $.each(args, function (i_dtd, v_dtd){
    17             v_dtd.done(argSolve);
    18         });
    19 
    20         return dtd.promise();
    21     }
    22 });

    调用也改成我们自己的方法:

    1 $.myWhen(fA(), fB()).done(function(){
    2        console.log('when fA, fB is solved');
    3 });

    打开控制台:

    fa Start
    fb Start
    fa End
    fb End
    when fA, fB is solved

    看来我们的myWhen 成功了。这个只是我们为了学习而造的轮子,下面的例子还是用$.when()  

    第三步,同时执行fC、fD,只要有一个成功就执行fE。

    问题来了,$.when是与门开关,那么有没有或门开关呢?好像jquery还真没准备。不过我们有了上面造轮子的经验,相信应该很容易造一个$.myAtLeast()

     1 "myAtLeast": function(){
     2         var args = arguments;
     3         var dtd = $.Deferred();
     4         var hasResolve = false;
     5         var solve = function(){
     6             if(!hasResolve){
     7                 dtd.resolve();
     8             }
     9         };
    10         $.each(args, function (i_dtd, v_dtd){
    11             v_dtd.done(solve);
    12         });
    13         return dtd.promise();
    14     }

    调用一下试试:

    1     $.when(fA(), fB()).done(function(){
    2         console.log('when fA, fB has resolved');
    3         $.myAtLeast(fC(), fD()).done(function(){
    4             console.log('fC or fD has resolved');
    5             fE();
    6         });
    7     });

    打开控制台: 

     1 fa Start
     2 fb Start
     3 fa End
     4 fb End
     5 when fA, fB has resolved
     6 fC Start
     7 fD Start
     8 fC End
     9 fC or fD has resolved
    10 fE Start
    11 fD End
    12 fE End

    我们可以清楚的看到,fC End后, fE就执行了,随后fD才结束。

    就此,我们实现了,一开始定义的需求。

    写的仓促,望大家指出文章中不对的地方。谢谢!

  • 相关阅读:
    css字体图标的制作和使用。
    js日期插件bootstrap-datetimepicker的使用
    vue.js学习笔记(二):如何加载本地json文件
    vue.js学习笔记(一):什么是mvvm框架,vue.js的核心思想
    总结XX网app中webapp常见的前端错误。
    EffectiveJava——接口优于抽象类
    EffectiveJava——复合优先于继承
    java多线程(三)——锁机制synchronized(同步语句块)
    java多线程(二)——锁机制synchronized(同步方法)
    java多线程(一)——线程安全的单例模式
  • 原文地址:https://www.cnblogs.com/webARM/p/5064141.html
Copyright © 2011-2022 走看看