jQuery的deferred延时对象

1.作用

deferred对象是一个延迟对象,意思是函数延迟到某个点才开始执行,改变执行状态的方法有两个(成功:resolve和失败:reject),分别对应两种执行回调(成功回调函数:done和失败回调函数fail)

2.$.when()

【文字转载于菜鸟教程】 deferred1.html
在多个延迟对象传递给jQuery.when() 的情况下,该方法返回一个新的"宿主"延迟对象,当所有的延迟对 象被受理(resolve)时,该方法才会受理它的宿主延迟对象。当其中有一个延迟对象被拒绝(rejected)时, 该方法就会拒绝它的宿主延迟对象。当宿主对象被受理时,doneCallbacks(受理回调)将被执行。

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
	var d1 = $.Deferred();
	var d2 = $.Deferred();
	var d3 = $.Deferred();
	$.when( d1, d2, d3 ).done(function ( v1, v2, v3 ) {
		console.log( v1 ); // v1 is undefined
		console.log( v2 ); // v2 is "abc"
		console.log( v3 ); // v3 is an array [ 1, 2, 3, 4, 5 ]
	});
	d1.resolve();
	d2.resolve( "abc" );
	d3.reject( 1, 2, 3, 4, 5 );
</script>

</body>
</html>

3. $.Deferred()

deferred对象的链式调用 deferred2.html
参照:https://www.runoob.com/jquery/misc-jquery-deferred.html
then()

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
	$.Deferred(function(dfd){
    setTimeout(function(){
        console.log("1执行完毕!");
        dfd.resolve(1);
		},4000);
		return dfd;
	})
	.then(function(value){
		var deferred = $.Deferred();
		setTimeout(function(){
			console.log("2执行完毕!");
			deferred.resolve(value + 1);
		},3000);
		return deferred;
	})
	.then(function(value){
		var deferred = $.Deferred();
		setTimeout(function(){
			console.log("3执行完毕!" + value);
			deferred.resolve();
		},2000);
		return deferred;
	});
</script>
</body>
</html>

4.done()与then()区别

done返回当前的的deferred object,当前done方法中callback的返回值不会被传递 deferred3.html
then返回一个新的deferred object,当前then方法中callback的返回值会被传递(参考jquery的pipe属性)给新的callback

jquery的deferred对象的done方法和then方法都能实现链式调用,但是他们的作用是有区别的,then方法中如果你传递的方法有返回值,那么他会传递给下一个链式调用的方法。而done方法与此相反,你传递的方法就算有返回值,done方法也不会把你的返回值传给下一个链式调用的方法的。

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
	$.Deferred(function(dfd){
    setTimeout(function(){
        console.log("1执行完毕!");
        dfd.resolve(1);
		},4000);
		return dfd;
	})
	.done(function(value){
		var deferred = $.Deferred();
		setTimeout(function(){
			console.log("2执行完毕!");
			deferred.resolve(value + 1);
		},3000);
		return deferred;
	})
	.done(function(value){
		var deferred = $.Deferred();
		setTimeout(function(){
			console.log("3执行完毕!" + value);
			deferred.resolve();
		},2000);
		return deferred;
	});
</script>
</body>
</html>
结果:
1执行完毕!
deferred3.html:29 3执行完毕!1
deferred3.html:21 2执行完毕!

5.then() 同上

deferred4.html

<head>
  <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
	var dfd = function() {
		var deferred = $.Deferred();
		setTimeout(function() {
			console.log("执行完毕1");
			deferred.resolve(1);
	  },2000);
		return deferred;
	};

	$.when(dfd())
	.then(function(value){
		var deferred = $.Deferred();
		setTimeout(function() {
			console.log("执行完毕2");
			console.log('value = ' + value);
			deferred.resolve(value + 1);
		},3000);
		return deferred;
	})
	.then(function(value){
		var deferred = $.Deferred();
		setTimeout(function() {
			console.log("执行完毕3");
			console.log('value = ' + value);
			deferred.resolve(value + 1);
		},2000);
		return deferred;
	});
</script>
 
</body>
</html>

6.then()与done()结合使用

	var defer = jQuery.Deferred();
        defer.done(function (a, b) {
            console.log("a = " + a + "b = " + b);  //2,3  d1.resolve(2,3)
            return a * b;
        }).done(function (result) {
            console.log("result = " + result);  //2 d1.resolve(2,3)
        }).then(function (a, b) {
            console.log("a = " + a + "b = " + b);  //2,3  d2.resolve(6)
            return a * b;
        }).done(function (result) {
            console.log("result = " + result);   //6   d2.resolve(6)
        }).then(function (a, b) {
            console.log("a = " + a + "b = " + b);    //6,undefined  d2.resolve(6)
            return a * b;						    //d3.resolve(NaN)
        }).done(function (result) {
            console.log("result = " + result);   //NaN
        });
        defer.resolve(2, 3);  //d1

分析:
1、第一个done和第二个done都返回了defer.resolve( 2, 3 )
2、done中callback的返回值不会被传递
3、第二个done只有一个参数,接收了defer.resolve( 2, 3 )的第一个参数2,所以result是2
4、第一个then接收defer.resolve( 2, 3 ),接收两个参数,result是6,同时新建一个deferred object,传递result给deferred object
5、第三个done接收到了这个新的deferred object和传递的result,打印结果是6,并把这个新的deferred object传递给第二个then
6、第二个then现在接收新的deferred object,它只有一个参数,是result,所以参数b没有定义,返回的结果是NaN,同时又新建一个deferred object
7、第四个done接收一个新建的deferred object,传递的参数是NaN,打印的结果自然就是NaN
deferred.done() 函数当Deferred(延迟)对象被受理时,调用添加的处理程序。
提示:该方法接受一个或者多个参数。deferred.done() 返回的是一个 Deferred 对象, 可以连接其他的延迟对象方法,包括额外的 .done() 方法。当Deferred 对象得到解决时,回调函数按它们被添加时的顺序执行,并且可以作为参数传递给如下的方法使用:resolve,resolveWith。【参照csdn博文】

7. done()与then()总结

deferred.done也没有对应任何原生Promise方法,千万不要以为deferred.done对应单参数的new Promise().then,因为deferred.done连缀书写的话,各个回调函数是并列关系,回调函数里面如果有异步任务,会导致执行顺序不符合你的期待。可以使用deferred.then连缀来解决这个问题。
(3)deferred.then是jQuery中唯一可以传递延迟状态的方法。其实在1.8版本之前,没有任何方法可以传递延迟状态,只不过1.8版本开始,jQ的开发者们给then赋予了传递延迟状态的能力,这时候,很多使用者误以为done和fail等也可以传递延迟状态,其实并不是,记住,直至本文完稿为止,只有then方法有这个能力
再具体说,就是then方法后面可以接done、fail等方法,then可以把延迟状态传递给done和fail等方法,但是,done、fail方法后面不可以接then方法,说白了done、fail就是延迟链的终点,不会再有延迟对象传递。这跟原生Promises是不一样的。【参照博文】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值