原文地址:http://www.cnblogs.com/lvdabao/p/jquery-deferred.html?utm_source=tuicool&utm_medium=referral
看过第一篇,再看jquery领悟很多。
jquery的defferd和ES6中的有很大不同,概念类似,名称不同。尤其是Deferred和ajax的关系,现在也搞不清
1、声明一个Deferred
var def = $.Deferred(); //定义一个defferd对象
setTimeout(function(){
console.log('执行完成');
def.resolve('随便什么数据'); //此处和ES6的区别
}, 2000);
return def; //建议返回 def.promise(); 其实他就是一个返回受限Deferred对象的方法,防止外部乱用
2、Jquery的Deferred的三个状态:pending resolved rejected
通过def.state()来返状态。
3、jquery文档中写:
我不太好理解这个filter,还是想用fun来表述这个参数的意思,于是相当于:
var def = $.Deferred();
def.then(doneFun,failFun,progressFun);
由这三个函数来为执行的结果进行响应。ES6中只有成功或失败两个状态,jquery来扩充了一下正执行这么一个状态。
4、比较:done,fail,progress 的区别
完成 | 失败 | 待定 | |
---|---|---|---|
状态 | resolved | rejected | pending |
触发的命令 | def.resolve("XXXX"); | def.reject("XXXX"); | def.notify("XXXX"); |
执行状态回调 | def.done( doneFun ); | def.fail( failFun ); | def.progress( progressFun) |
then执行回调 | doneFun | failFun | progressFun |
jquery的同义词 | $.ajax().success() | $.ajax().error() |
猛地一看,可能不太懂,我把我测试代码贴上就明白了
def = $.Deferred()
def.done(function(data) { console.log("完成" + data); }) //d.resolve("xxxx")来触发
.fail(function(data) { console.log("未完成" + data); }) //d.reject("xxxx")来触发
.progress(function(data) { console.log("进行中" + data); }) //d.notify("xxxx")来触发
//以下代码功能同上。
def = $.Deferred()
def.then(function(data) { console.log("完成" + data); },
function(data) { console.log("未完成" + data); },
function(data) { console.log("进行中" + data); })
//以下为触发代码:
def.notify(1) // 进行中1
def.notify(50) // 进行中50
def.resolve("done") // 完成done
def.notify(100) // 无任何效果。也就是说只有在pending时,才能notify.
5、def.always( alwaysFun ) 无论成功失败,都执行该函数。
经测,def.notify() 不会触发alwaysFun. ajax中的同义词为:$.ajax().complete( )
6、$.when的用法
和Es6不同的是,接受的不是一个数据。then响应的值数据时,也不是数据。记住这个格式即可
$.when(runAsync(), runAsync2(), runAsync3())
.then(function(data1, data2, data3){
console.log('全部执行完成');
console.log(data1, data2, data3);
});
jquery中没有像ES6中的race方法。
7、ajax与Deferred的关系
该部分照抄原文。没什么好补充的,请记住只用done,fail,always即可。
jquery的ajax返回一个受限的Deferred对象,还记得受限的Deferred对象吧,也就是没有resolve方法和reject方法,不能从外部改变状态。
$.ajax(/*...*/)
.success(function(){/*...*/})
.error(function(){/*...*/})
.complete(function(){/*...*/})
分别表示ajax请求成功、失败、结束的回调。这三个方法与Deferred又是什么关系呢?其实就是语法糖,success对应done,error对应fail,complete对应always,就这样,只是为了与ajax的参数名字上保持一致而已,更方便大家记忆,看一眼源码:
deferred.promise( jqXHR ).complete = completeDeferred.add;
jqXHR.success = jqXHR.done;
jqXHR.error = jqXHR.fail;
complete那一行那么写,是为了减少重复代码,其实就是把done和fail又调用一次,与always中的代码一样。deferred.promise( jqXHR )这句也能看出,ajax返回的是受限的Deferred对象。
jquery加了这么些个语法糖,虽然上手门槛更低了,但是却造成了一定程度的混淆。一些人虽然这么写了很久,却一直不知道其中的原理,在面试的时候只能答出一些皮毛,这是很不好的。这也是我写这篇文章的缘由。
jquery中Deferred对象涉及到的方法很多,本文尽量分门别类的来介绍,希望能帮大家理清思路。总结一下就是:$.Deferred实现了Promise规范,then、done、fail、always是Deferred对象的方法。$.when是一个全局的方法,用来并行运行多个异步任务,与ES6的all是一个功能。ajax返回一个Deferred对象,success、error、complete是ajax提供的语法糖,功能与Deferred对象的done、fail、always一致。就酱。