jQuery的deferred对象使用详解
之前看别人的demo,发现在延迟对象被resolve时要执行的代码,有时会写在deferred.then方法里执行,有时会写在deferred.done方法里执行。
这让对延迟对象一知半解的我非常困惑,今天抽时间研究了一下下,发现:在某种环境下,两个方法的确能实现同样的效果。
这种特定的环境是怎样呢?
先看一下deferred.done的用法:
//创建deferred对象 vardtd=$.Deferred(); //解决deferred对象 dtd.resolve('finish'); //调用done方法 dtd.done(doneCallback[,doneCallback]) //当deferred对象被resolve时,执行doneCallback函数 //参数可为一个函数、多个函数或函数数组 //返回原来的deferred或promise对象
再看下deferred.then的用法和特性:
//创建deferred对象 vardtd=$.Deferred(); //解决deferred对象 dtd.resolve('finish'); //调用then方法 deferred.then(doneFilter[,failFilter][,progressFilter]) //then方法特性: //当deferred对象被resolve时,执行doneFilter函数 //当deferred对象被reject时,执行failFilter函数 //当dederred对象被progress时,执行progressFilter函数 //返回值:1,返回deferred的promise对象,可修改promise传递的值(原来resolve,reject的返回值为a,将a修改为b,返回b,该promise的done或fail收到的返回值变为b); //返回值:2,在then方法内创建新的deferred对象并返回其promise //返回的promise对象可以链接其他的延迟对象,如done,fail,then等 //多个then方法时,异步执行(onebyone) //该方法会过滤掉deferred修改状态的方法,返回值deferred对象的promise
根据以上两个方法的特性,发现:
deferred.then和deferred.done方法都可以直接收一个参数函数,且第一个参数函数都是在deferred对象在resolve时被调用。
虽说then方法可改变返回值,但在不考虑返回值且只有一个参数函数的前提下,两个方法的确可以实现一样的效果。
相比之下,done方法更纯粹吧,then方法会更复杂一些,但不能完全替代done方法,使用then方法的话,还是小心些的好。
附Deferred对象的其它方法:
//创建延迟对象<br>vardtd=$.Deferred(); varstate=dtd.state(); //返回deferred对象当前状态,pending/resolved/rejected //不接受任何参数 deferred.always(alwaysCallback[,alwaysCallback]); //当deferred对象被解决或拒绝时,都执行此方法 //参数可以是一个函数,或是一个函数数组 dtd.promise([obj]); //目的:防止其他代码干涉其内部进度和状态 //返回新的promise对象,包含可以执行的方法(done,fail,then,always,progress,state,promise), //不包含修改Deferred状态的方法(resolve,reject,notify,resolveWith,rejectWith,nodifyWith) //需返回deferred对象时,建议返回deferred.promise() dtd.resolve([args]) //解决deferred对象,调用所有doneCallback函数 //doneCallback可通过then方法中第一个参数设置,也可通过dtd.done(doneCallback)添加 //参数将传递给doneCallback。参数可选 //只有deferred对象的创建者才可以调用的方法 //doneCallback中this为deferred或promise对象 //doneCallback只接收一个参数 dtd.resolveWith(context[,args]) //解决deferred对象,调用所有doneCallback函数 //参数:第一个参数为上下文即this对象,doneCallback的this将被修改;第二个参数为数组 //doneCallback中this为调用resolveWith方法的上下文 //doneCallback接收参数个数为该方法第二个参数数组的长度 //与resolve方法的区别在于,将改变doneCallback函数的this指向 dtd.reject([args]) //拒绝deferred对象,调用所有failCallback函数 //failCallback可通过then方法中第二个参数设置,也可通过dtd.fail(failCallback)添加 //参数将传递给failCallback。参数可选 //只有deferred对象的创建者才可以调用的方法 //failCallback中this为deferred或promise对象 //failCallback只接收一个参数 dtd.rejectWith(context,[args]) //解决deferred对象,调用所有failCallback函数 //参数:第一个参数为上下文即this对象,failCallback的this将被修改;第二个参数为数组 //failCallback中this为调用rejectWith方法的上下文 //failCallback接收参数个数为该方法第二个参数数组的长度 //与resolve方法的区别在于,将改变failCallback函数的this指向 dtd.notify([args]) //deferred进行处理时,调用所有的progressCallback函数 //progressCallback可通过then方法中的第3个参数设置,也可以通过deferred.progress(progressCallback)添加 //通常此方法只能被deferred对象的创建者调用,可通过deferred.promise或then过滤此方法 //参数可不写。若写有参数,建议为字符串或可返回字符串的函数 //当deferred进入resolved或rejected状态后,再调用notify方法,progressCallback将不再被执行 dtd.notifyWith(context,[args]) //deferred进行处理时,调用所有progressCallback函数 //参数:第一个参数为上下文即this对象,progressCallback的this将被修改;第二个参数为数组 //progressCallback中this为调用rejectWith方法的上下文 //progressCallback接收参数个数为该方法第二个参数数组的长度 //与resolve方法的区别在于,将改变progressCallback函数的this指向 //当deferred进入resolved或rejected状态后,再调用notifyWith方法,progressCallback将不再被执行