之前用angular的$http向接口发起请求,里面的回调写法感觉很好看,最近用jquery,也找到相同的写法,展示于此处。
jq Ajax中的Promise
常规的ajax
写法:
1 | $.ajax({ |
为了方便使用ajax
,封装如下:
1 | function AjaxServer(url,data){ |
那么,这个AjaxServer
返回的是什么呢?是一个XMLHttpRequest
(jqXHR
)对象,从jQuery1.5开始,该对象实现了Promise
接口, 使它拥有了 Promise
的所有属性、方法和行为。可参考:jQuery.Deferred对象
然后就可以这样调用ajax:
写法1
1 | AjaxServer(url,data).done(function(data, textStatus, jqXHR){ |
写法2
1 | AjaxServer(url,data).then(function(data, textStatus, jqXHR) { |
从angular沿袭下来的习惯,我比较喜欢写法2。
Tip:在调用接口失败时或者接口返回的值不是我们期望的值时,我们经常需要提示,但这两种情况的提示一般是相近的(如果要求不严格的话),所以为了简练,可以这样写:
1 | AjaxServer(url,data).always(function(result,textStatus,obj){ |
jQuery.Deferred对象
基本用法:强制同步(以点击事件触发为例)
html:
1 | <input type="text" value="小明" id="name"> |
js:
1 | function search(){ |
点击”查询”按钮的输出结果为:
从结果可以看出:resolve()
触发了done(callback)
。其实:
- defer.resolve():触发 done 的回调执行,并传值给回调方法。
- defer.reject():触发 fail 的回调,并传值给回调方法。
- defer.notify():触发 progress 的回调,并传值给回调方法。
另外:上面这三个方法都会触发 always 的回调
链式调用
有这样三个方法,让他们链式调用
1 | function delay(){ |
写法1
1 | function search(){ |
结果如图:
写法2
1 | function search(){ |
结果同写法1
$.when()
接受一个Promise对象,$.when更多介绍
如果写作:
1 | $.when(delay()).then(animate()).then(click1()); |
那就相当于
1 | $.when(delay(),animate(),click1()); |
其结果是:三个方法异步一起执行。
备注:promise与defer的区别
promise:promise 对象是没有 resolve , reject , notify 等方法的,也就意味着,你无法针对 promise 对象进行状态更改,只能在 done 或 fail 中进行回调配置。promise相当于defer对象的子集。