嗯、看例子吧(初学,主要是为了理解deferred对象,不合理之处还请指教)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dfd</title>
<style>
*{padding:0; margin:0;}
#wrap{margin:30px auto;display:flex; align-items:center; width:800px; justify-content:center; }
#btn{width:80px; height:30px; background-color:greenyellow;}
#ul1{width:600px; display:flex; flex-wrap:wrap;}
li{list-style:none; width:200px; height:100px; margin-top:10px; background-color:#e5ebf0;}
img{width:200px; height:100px; margin-left:2px;}
</style>
</head>
<body>
<div id="wrap">
<input type="button" id="btn" value="添加图片"/>
<ul id="ul1">
<li><img id="img" src="img/1.jpg"/></li>
</ul>
</div>
<script src="jquery-1.11.1.js"></script>
<script>
$(function(){
var $img = $('#img');
var $Ul = $('#ul1');
var $btn = $('#btn');
var arr = ["img/1.jpg","img/2.jpg","img/3.jpg","img/4.jpg","img/5.jpg","img/6.jpg"];
var dtd = $.Deferred();//创建延迟对象
var i = 0;
setTimeout(function(){
dtd.resolve();//点击按钮3秒后将dtd状态变为已完成
},3000);
$btn.click(function(){
dtd.done(fn);//操作成功时执行该回调函数(添加图片的操作)
});
function fn(){
i++;
if(i==arr.length){
i = 0;
}
var $li = $(`<li><img id="img" src=${arr[i]}/></li>`);
$Ul.append($li);
}
})
</script>
</body>
</html>

上面的代码中,当页面加载后,第一次点击加载图片按钮时,延迟3秒后才加载,而后面再点击,就立即加载了图片,这里我们就用到了延迟对象deferred

那么什么是延迟对象呢?看了阮一峰大神的日志,上面写得很详细,所以就不再搬砖了,有兴趣的请点击​​http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object​

下面我主要把我自己用到的总结一下

jQuery规定,deferred对象有三种执行状态,未完成,已完成和已失败。如果执行状态是“已完成(resolved)”,deferred对象立刻调用done()方法指定的回调函数,如果执行状态是“已失败”,调用fail()方法指定的回调函数,如果状态是“未完成”,则继续等待,或者调用progress()方法指定的回调函数。

这也就是为什么,只有第一次点击的时候,延迟3秒后才执行添加图片的操作,而后面立即执行该操作,就是因为第一次点击之后状态变为了已完成,所以后面执行,函数都是立即执行。

deferred对象的方法

$.Deferred()//生成一个延迟(deferred)对象
deferred.done()//指定操作成功时的回调函数
deferred.fail()//指定操作失败时的回调函数
deferred.promise()//没有参数时,返回一个新的deferred对象,该对象的运行状态无法改变;接收参数时,作用为在参数对象上部署deferred接口
deferred.resolve()//手动改变deferred对象的运行状态为“已完成”,从而立即触发done()方法
deffered.reject()//手动改变deferred对象的运行状态为“已失败”从而立即触发fail方法
$.when()//为多个操作指定回调函数
$.then()//如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail的回调函数,如果只有一个参数,那么等同于done()方法
deferred.always()//这个方法是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve(),还是deferred.reject(),最后总是执行