如何使用jquery中deferred对象?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
什么是 deferred 对象?
延迟对象,在jQuery的1.5引入,是通过调用jQuery.Deferred()方法创建一个可链式调用的工具对象。 它可以注册多个回调到回调队列, 调用回调队列,准备代替任何同步或异步函数的成功或失败状态。——jQuery API中文文档简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。——阮一峰
deferred 对象的主要功能
ajax 操作的链式写法
$.ajax("test.html") .done(function(){ alert("success"); }) .fail(function(){ alert("error"); });
$.ajax() 操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,无法进行链式操作;如果是高于1.5.0版本,返回的是deferred对象,可以进行链式操作。可以看到,done() 相当于 success 方法,fail() 相当于 error 方法。采用链式写法以后,代码的可读性大大提高。
这里着重强调一下 jqXHR 对象,从 jQuery 1.5 开始, $.ajax() 返回的 jqXHR对象 本身就是 deferred 对象,因此可以像上面代码中那样进行链式调用。
从 jQuery 1.5 开始,$.ajax()返回的jqXHR对象 实现了 Promise 接口, 使它拥有了 Promise 的所有属性,方法和行为。(见Deferred object获取更多信息)。为了让回调函数的名字统一,便于在$.ajax()中使用。jqXHR也提供.error() .success()和.complete()方法。这些方法都带有一个参数,该参数是一个函数,此函数在 $.ajax()请求结束时被调用,并且这个函数接收的参数,与调用 $.ajax()函数时的参数是一致。这将允许你在一次请求时,对多个回调函数进行赋值,甚至允许你在请求已经完成后,对回调函数进行赋值(如果该请求已经完成,则回调函数会被立刻调用)。
注意事项: jqXHR.success(), jqXHR.error(), 和 jqXHR.complete() 回调从 jQuery 1.8开始 被弃用过时,从jQuery 3.0开始被删除,你可以使用 jqXHR.done(), jqXHR.fail(), 和 jqXHR.always() 代替。
指定同一操作的多个回调函数
deferred 对象的一大好处,就是它允许你自由添加多个回调函数。还是以上面的代码为例,如果ajax操作成功后,除了原来的回调函数,我还想再运行一个回调函数,怎么办?很简单,直接把它加在后面就行了。
$.ajax("test.html") .done(function(){ alert('success'); }) .fail(function(){ alert('error'); }) .done(function(){ alert('第二个回调函数!'); });
回调函数可以添加任意多个,它们按照添加顺序执行。
为多个操作指定回调函数
deferred 对象的另一大好处,就是它允许你为多个事件指定一个回调函数,这是传统写法做不到的。
请看下面的代码,它用到了一个新的方法 jQuery.when():
$.when($.ajax("test1.html"), $.ajax("test2.html")) .done(function(){ alert('success'); }) .fail(function(){ alert('error'); });
这段代码的意思是,先执行两个操作$.ajax("test1.html")和$.ajax("test2.html"),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数。
$.when() 方法的使用具体 参见文档。
普通操作的回调函数接口
deferred 对象的最大优点,就是它把这一套回调函数接口,从ajax操作扩展到了所有操作。也就是说,任何一个操作----不管是ajax操作还是本地操作,也不管是异步操作还是同步操作----都可以使用deferred对象的各种方法,指定回调函数。
我们来看一个具体的例子,为一个很耗时的操作 wait 指定回调函数:
var wait = function (dtd) { var dtd = $.Deferred(); // 在函数内部,新建一个Deferred对象 var tasks = function () { alert('执行完毕!'); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks, 5000); return dtd.promise(); // 返回promise对象 }; $.when(wait()) .done(function () { alert('success'); }) .fail(function () { alert('error'); });
另一种做法是直接将 wait 函数传入 $.Deferred()
:
$.Deferred(wait) .done(function(){ alert('success'); }) .fail(function(){ alert('error'); });
jQuery 规定,$.Deferred()
可以接受一个函数名(注意,是函数名)作为参数,$.Deferred()
所生成的 deferred 对象将作为这个函数的默认参数。
更具体的信息请参见 阮一峰的文档。
deferred 对象的方法
$.Deferred() 生成一个 deferred 对象。
jQuery.Deferred( [beforeStart ] ) 工厂函数创建一个新的deferred对象。
描述: 一个工厂函数,这个函数返回一个链式实用对象,用返回对象方法来在回调队列中注册多个回调, 调用回调队列,传递任何同步或异步函数的成功或失败状态。
beforeStart : 类型 Function( Deferred deferred ),一个构造函数返回之前调用的函数。
jQuery.Deferred 方法可以传递一个可选的函数, 这个函数在方法返回之前调用,并且会把新的 deferred(延迟)对象作为 this 对象,将其作为第一个参数传递给函数。例如,被调用的函数可以使用 deferred.then() 绑定回调。
deferred.done() 指定操作成功时的回调函数。
deferred.fail() 指定操作失败时的回调函数。
deferred.promise() 没有参数时,返回一个新的 deferred。 对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署 deferred 接口。
deferred.resolve() 手动改变 deferred 对象的运行状态为"已完成",从而立即触发 done() 方法。
一个 Deferred(延迟)对象开始于 pending 状态。 任何回调使用 deferred.then(), deferred.always(), deferred.done(), 或者 deferred.fail() 添加到这个对象都是排队等待执行。调用 deferred.resolve() 转换 Deferred(递延)到 resolved(解决)的状态,并立即执行设置中任何的 doneCallbacks。调用 deferred.reject() 转换 Deferred(递延)到 rejected(拒绝)的状态,并立即执行设置中任何的 failCallbacks。一旦对象已经进入了解决或拒绝状态,它处于该状态。回调仍然可以添加到解决或拒绝 Deferred(递延)- 他们会立即执行。
$.ajax() 返回的 jqXHR 对象 会根据请求返回的结果,自动改变自身的执行状态。但是,对于其他通过 $.Deferred() 方法生成的 deferred 对象,它们的执行状态必须由程序员手动指定,由代码决定在什么时候触发回调函数。
deferred.reject() 这个方法与 deferred.resolve() 正好相反,调用后将 deferred 对象的运行状态变为"已失败",从而立即触发 fail() 方法。
$.when() 为多个操作指定回调函数。
deferred.then() 方法
有时为了省事,可以把 done() 和 fail() 合在一起写,这就是 then() 方法。
$.when($.ajax( '/main.php' )) .then(successFunc, failureFunc);
如果 then() 有两个参数,那么第一个参数是 done() 方法的回调函数,第二个参数是 fail() 方法的回调方法。如果 then() 只有一个参数,那么等同于 done()。
deferred.always() 方法
这个方法也是用来指定回调函数的,它的作用是,不管调用的是 deferred.resolve() 还是 deferred.reject(),最后总是执行。
$.ajax( 'test.html' ) .always( function() { alert('已执行!');} );
看完上述内容,你们掌握如何使用jquery中deferred对象的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。