• jquery管理ajax异步-deferred对象


    今天跟大家分享一个jquery中的对象-deferred。其实早在jquery1.5.0版本中就已经引入这个对象了。不过可能在实际开发过程中用到的并不多,所以没有太在意。

    这里先不说deferred的概念,我们先看一个例子。

    还记得初学的时候,遇到一个实例,先是要ajax请求一个接口(a.json),从返回的数据中获得一个id1值。然后再请求一个接口(b.json)获得id2,最后需要对这两个id值同时进行操作。

    错误解法

    那个时候初学,首先想到的方案(现在想想,很傻很天真...)

    var id1, id2;
    $.ajax({
    	url: 'a.js',
    	dataType: 'json',
    	type: 'get',
    	success: function(d){
    		id1 = d.item.id;
    	}
    });
    $.ajax({
    	url: 'b.js',
    	dataType: 'json',
    	type: 'get',
    	success: function(d){
    		id2 = d.item.id;
    	}
    })
    
    alert('id1='+id1+','+ 'id2='+ id2);
    

    因为那个时候,还没有理解异步的概念,所以以为,第二次ajax的时候id已经有值了,但是运行之后才发现,变量id其实根本没被赋值。想要测试上面代码,点这里

    也就是这一刻,我真正明白了:ajax是异步的!!!

    傻瓜式解法

    发现上面那个方法不能用之后,分析了一下,弹出undefined是因为弹出之前id还没有被赋值,那我保证在弹出之前给id赋值不就解决了吗?好的,于是我想到了下面这个方法:

    var id1;    
    $.ajax({
    	url: '/test/json/a.js',
        dataType: 'json',
        type: 'get',
        success: function(d){
            id1 = d.item.id;
            $.ajax({
           	    url: '/test/json/b.js',
                dataType: 'json',
                type: 'get',
                success: function(f){
                	id2 = f.item.id;
                    alert('id1='+id1+','+ 'id2='+ id2);
                }
            });
        }
    })
    

    想要测试上面代码,点这里

    逻辑虽然正确了,但总觉得怪怪的,如果这里需要嵌套3层呢?4层呢?。。。ajax里面嵌套ajax,如果数据很多,访问速度慢,嵌套更多层,会导致性能下降、影响用户体验、代码不好维护等等问题。所以一般不推荐这种方法。总之,这种写法让我难以接受。

    所以思来想去,觉得不妥。。。然后那个时候就在一个前端群里,询问各种大牛,直到一个大牛告诉我让我百度一下deferred,后来认真学习了下,觉得不错。

    使用deferred对象

    deferred对象简介

    deferred是jquery中的扩展的一个对象(1.5.0以上的版本支持deferred)。defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。

    简单说,deferred对象就是jQuery的回调函数解决方案。

    再简单说,deferred对象用来管理异步操作,而ajax就是一种异步操作。

    deferred基本语法

    deferred让ajax支持新的写法,代码如下:

    $.ajax({
    	url: '/test/json/a.js',
    	dataType: 'json',
    	type: 'get'
    })
    .done(function() {
    	alert("成功啦!");
    })
    .fail(function() {
        alert("失败了...");
    })
    

    想要测试上面代码,点这里

    这个大家应该都知道。现在在编辑器敲入ajax,然后回车,提示的ajax语法结构就是这样链式的写法。

    done函数就是ajax请求成功的回到函数;
    fail函数就是ajax请求失败的回调函数。

    使用deferred的解决方法

    var ajax1 = $.ajax({
    	url: '/test/json/a.js',
    	dataType: 'json',
    	type: 'get'
    });
    var ajax2 = $.ajax({
    	url: '/test/json/b.js',
    	dataType: 'json',
    	type: 'get',
    });
    $.when(ajax1,ajax2).done(function(d1,d2){
    	var id1 = d1[0].item.id;
    	var id2 = d2[0].item.id;
    	alert('id1='+id1+',   '+ 'id2='+ id2);
    }).fail(function(){
    	alert('error');
    });
    

    值得一提的是,上面代码中done函数的参数,对应的是前面每一个ajax请求返回的数据

    想要测试上面代码,点这里

    上面的代码中,用到了deferred对象的when方法。
    它的描述是:

    提供一种方法来执行一个或多个对象的回调函数。

    这里的ajax1和ajax2就是deferred对象,done和fail就是回调函数。上面代码的意思是:

    只有当两个ajax请求都成功返回数据时,执行done函数;只要有一个请求不成功,就执行fail函数。

    另外值得一提的是:$.when方法的参数,只支持deferred对象,而ajax返回的就是deferred对象。`

    这就已经实现了上面的需求了。请求两个接口,获得两个数据,都成功时,对这两个数据同时进行处理。而且这种链式写法,让读者一目了然,而且便于维护扩展。

    deferred方法汇总

    提到的方法

    • $.Deferred():生成一个deferred对象。

    • $.when() 为多个操作指定回调函数。

    • deferred.done():指定操作成功后的回调函数

    • deferred.fail():指定操作失败后的回调函数

    未提到的方法

    • deferred.resolve()方法和deferred.reject()方法

    deferred对象执行回调函数之前会有一个执行状态的存在,执行状态一共有三种———未完成、已完成和已失败。

    未完成状态,则会继续等待,或者执行progress()指定的回调函数。

    已完成状态,则会执行done()方法指定的回调函数。

    已失败状态,则会执行fail()方法指定的回调函数。

    所以这里的deferred.resolve()方法就是手动将deferred对象的状态改为已完成,继而执行done方法; deferred.reject()方法就是手动将状态改为已失败,继而执行fail方法。

    下面来看一个例子:

       	   var defer = $.Deferred(); // 新建一个Deferred对象
        var wait = function(defer){
            var tasks = function(){
               		defer.resolve();   // 改变Deferred对象为已完成状态
            		alert("执行完毕!");
            };
            setTimeout(tasks,5000);
            return defer;
          };
           $.when(wait(defer))
          .done(function(){
          		 alert("succeed"); 
          	})
          .fail(function(){
           	alert("failed"); 
          });
    

    想要测试上面代码,点这里

    结果:等待5秒钟,先弹出“succeed”,在弹出“执行完毕!”。

    分析一下代码执行过程:

    $.when()里面的参数是wait函数,也就是一个deferred对象,所以可以继续执行setTimeout函数,等待5s,执行tasks函数,然后手动改变了状态为“已完成”,所以执行done方法,弹出“succeed”,然后弹出“执行完毕!”。

    • deferred.then():有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。

      function successFun(){
      	alert("yes");
      }
      function failFun(){
      	alert('fail');
      }
      $.when($.ajax({
      	url: '/test/json/a.js',
      	dataType:'json',
      	type: 'get'
      })).then(successFun, failFun);
      

      当then方法只有一个参数时,相当于done方法。当有两个参数时,第一个相当于done方法,第二个相当于fail方法。

      想要测试上面代码,点这里

    总结

    deferred对象通过对一个ajax请求的各种回调函数的控制,让jquery写ajax变的简单、容易维护、容易扩展。

  • 相关阅读:
    编写pl/sql时,报错
    ORA-00906 missing left parenthesis括号
    数仓理论
    查看oracle实例名
    Oracle 关键字
    oracle关键字作为字段名使用方法
    dump函数
    raw数据类型
    oracle同义词是什么意思?
    10 Useeful Tips for Writing Effective Bash Scripts in Linux
  • 原文地址:https://www.cnblogs.com/jarson-7426/p/5511734.html
Copyright © 2020-2023  润新知