jquery管理ajax异步-deferred对象

今天跟你们分享一个jquery中的对象-deferred。其实早在jquery1.5.0版本中就已经引入这个对象了。不过可能在实际开发过程当中用到的并很少,因此没有太在乎。html

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

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

错误解法

那个时候初学,首先想到的方案(如今想一想,很傻很天真...)ajax

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其实根本没被赋值。想要测试上面代码,点这里json

也就是这一刻,我真正明白了: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变的简单、容易维护、容易扩展。

相关文章
相关标签/搜索