jquery里面的deferred对象

 看到“jquery里面的deferred对象”这样的标题,你兴许会疑惑不解,jquery里面有deferred对象?在哪里,我什么时候用到过这个deferred对象?别说你没有用过,看下面的代码:

<script>
	var ret=$.ajax({
		type:'post',
		data:{},
		url:"MyServlet",
		success:function(data){
			console.log("调用成功");
		},
		error:function(data){
			console.log("调用失败");
		}
	});
	console.log(ret);
</script>

陌生吗?我们平常用jquery的ajax的时候,最常用的写法就是:

$.ajax({
		type:'post',
		data:{},
		url:"MyServlet",
		success:function(data){},
		error:function(data){}
});

我在上边只是加了个返回值,并把返回值打印了出来,返回值是什么呢?如下:

image.png

可以看到,jquery的ajax函数返回值是一个对象,而这个对象就是我今天要说的主角了:deferred对象。

除了我们上边的ajax写法比较常用之外,我们写也可以这样来写ajax代码:

<script>
	$.ajax({
		type:'post',
		data:{},
		url:"MyServlet",
	}).done(function(data){
		console.log("成功");
	}).fail(function(data){
		console.log("失败");
	});
</script>

执行结果:

image.png

为什么可以这样写,知道了吗?因为ajax返回的是deferred对象,而done和fail都是deferred对象的方法?到这里有必要解释一下什么是deferred对象了。

        defer翻译过来是"延迟"的意思,deferred对象的含义也可以按着这个方向来理解-------"延迟"到未来某个点再执行。这样说比较抽象,还是明白点说。我们可能遇到过这样的情况,b逻辑需要等待a完成之后再执行,而a执行完成的时间不确定,怎么确保b的执行正好在a完成之后呢?此时,我们可以把b称作a的回调函数,针对这个问题的解决,每种语言都有自己的实现方法,而jquery的解决方案就是deferred对象。

deferred对象解决了如何处理耗时操作的回调函数的问题。

明白了什么是deferred对象以及deferred对象为什么会出现,再来看看deferred对象的方法都是代表什么意思呢。我先列出来常用的,底下再分别演示:

      (1) $.Deferred():手动生成一个deferred对象。

  (2) deferred.done() :操作成功之后的回调函数,在ajax里面就相当于success

  (3) deferred.fail() :操作失败时的回调函数,在ajax里面就相当于error

  (4) deferred.promise()  返回一个新的deferred对象,该对象的运行状态无法被改变。deferred对象有三种状态:未完成、已完成、已失败

  (5) deferred.resolve() 手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法。

  (6)deferred.reject()  手动改变deferred对象的运行状态变为"已失败",从而立即触发fail()方法。

  (7) $.when(deferred1[,deferred2]) 为多个操作指定回调函数。

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

$.ajax({
		type:'post',
		data:{},
		url:"MyServlet",
	}).then(successFunc, failureFunc );

 

如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法。如果then()只有一个参数,那么等同于done()。

  (9)deferred.always():这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是要执行always()指定的回调函数。

先来看看always:

<script>
	$.ajax({
		type:'post',
		data:{},
		url:"MyServlet",
	}).done(function(data){
		console.log("成功");
	}).fail(function(data){
		console.log("失败");
	}).always(function(){
		console.log("我总是被执行");
	});
</script>

执行结果:

image.png

再来看看$.when的使用:

	$.when($.ajax("MyServlet"),$.ajax("MyServlet2")).done(function(){
		console.log("都执行完成了");
	});

$.when允许你传入一个或多个deferred对象,即可以执行一个或多个deferred对象的回调函数。

除了可以传入ajax返回的deferred对象,你还可以传入一个普通函数f,此时表示的是f执行完之后的回调函数。

 

有下面的代码:

<script>
	function fun1(){
		setTimeout("getData()",3000);
	}
	function  getData(){
		console.log("getData");
	}
	fun1();
</script>

我们知道,上边的代码含义是在3秒之后调用getData()函数,这是没有问题的,现在如果我想是想在getData()函数调用完成并成功返回结果之后你给我打印出“调用getData完成done”怎么实现呢?显然,这里牵涉到打印顺序的问题,如果你像下面这样写:

<script>
	function fun1(){
		setTimeout("getData()",3000);
	}
	function  getData(){
		console.log("getData");
	}
	 $.when(fun1()).done(function(){
		console.log("done");
	}).fail(function(){
		console.log("fail");
	});
</script>

得到的结果是下面这个样子:

image.png

显然,这个打印顺序并不符合要求“getData()函数调用完成并成功返回结果之后”。

需要改写为下面这个样子。

<script>
	function fun1(){
		var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象
		setTimeout(getData,3000);
		function  getData(){
			console.log("getData");
			dtd.resolve(); // 改变Deferred对象的执行状态为“已完成”,当Deferred对象对象
			//的状态改变为"已完成"的时候,就会立马触发done方法
		}
		return dtd.promise();//如果直接返回dtd,那么在fun1外部也可以改变resolve对象了,不安全。
		//dtd.promise();和dtd都是deferred对象,所不同的仅仅是前者屏蔽了resolve和reject方法
	}
	 $.when(fun1()).done(function(){
		console.log("done");
	}).fail(function(){
		console.log("fail");
	});
</script>

执行结果:

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值