章节
问答
课签
笔记
评论
占位
占位

Ajax的deferred实现

在异步机制这章我们详细的分析了 deferred 的设计,其中提供了 deferred.promise 方法就是把普通对象转化成 deferred 对象了ajax 就是把 deferred 对象给掺进去可以让整个 Ajax 方法变成了一个 deferred 对象,在Ajax方法中返回的是 jqXHR 一个包装对象,在这个对象里面混入了所有实现方法。

ajax: function(url, options) {
    var jqXHR = {} //ajax对象
    deferred = jQuery.Deferred()
    //转成deferred对象
    deferred.promise(jqXHR).complete = completeDeferred.add
    return jqXHR
}

jQuery.ajax 的版本迭代:

  • 从 jQuery 1.5 开始,$.ajax() 返回 XMLHttpRequest(jqXHR)对象,该对象是浏览器的原生的 XMLHttpRequest 对象的一个超集。例如,它包含 responseText 和 responseXML 属性,以及一个 getResponseHeader() 方法。当传输机制不是 XMLHttpRequest 时(例如,一个 JSONP 请求脚本,返回一个脚本 tag 时),jqXHR 对象尽可能的模拟原生的 XHR 功能。
  • 从 jQuery 1.5.1 开始, jqXHR 对象还包含了overrideMimeType 方法 (它在 jQuery 1.4.x 中是有效的,但是在 jQuery 1.5 中暂时的被移除)。.overrideMimeType() 方法可能用在 beforeSend() 的回调函数中,例如,修改响应的 Content-Type 信息头:
  • 为了让回调函数的名字统一,便于在$.ajax()中使用。jqXHR也提供.error() .success()和.complete()方法。这些方法都带有一个参数,该参数是一个函数,此函数在 $.ajax()请求结束时被调用,并且这个函数接收的参数,与调用 $.ajax()函数时的参数是一致。这将允许你在一次请求时,对多个回调函数进行赋值,甚至允许你在请求已经完成后,对回调函数进行赋值(如果该请求已经完成,则回调函数会被立刻调用)。

为了向后兼容 XMLHttpRequest ,jqXHR 对象将公开下列属性和方法:

readyState
status
statusText
responseXML and/or responseText 当底层的请求分别作出XML和/或文本响应
setRequestHeader(name, value) 从标准出发,通过替换旧的值为新的值,而不是替换的新值到旧值
getAllResponseHeaders()
getResponseHeader()
abort()


为了实现以上这些功能,jQuery 在对 jqXHR 做2个处理:

  1. 异步队列 deferred
  2. 回调队列 Callbacks
// Deferreds
deferred = jQuery.Deferred(),
//所有的回调队列,不管任何时候增加的回调保证只触发一次
completeDeferred = jQuery.Callbacks("once memory"),

给 jqXHR 扩充添加 promise 的属性和方法,然后添加 complete 方法,这里用的是回调列表的 add 方法(即添加回调)

deferred.promise(jqXHR).complete = completeDeferred.add;

此时的 jqXHR 就具有了 promise 的一些特性了与 callback 的回调列队了,当然这里有个重点,返回了一个只读的 deferred 对象,如果返回完整的 deferred 对象,那么外部程序就能随意的触发 deferred 对象的回调函数,很有可能在 AJAX 请求结束前就触发了回调函数(resolve),这就是与 AJAX 本身的逻辑相违背了。所以为了避免不经意间改变任务的内部流程,我们应该只返回 deferred 的只读版本 deferred.promise(),然后把对应的 done 与 fail 改成别名 success 与 error。

jqXHR.success = jqXHR.done;
jqXHR.error   = jqXHR.fail

 

我们还需要把用户自定的内部回调函数给注册到 jqXHR 对象上。

// 增加回调队列
for (i in {
    success  : 1,
    error    : 1,
    complete : 1
}) {
    /**
     * 把参数的回调函数注册到内部jqXHR对象上,实现统一调用
     * 给ajax对象注册 回调函数add
     * deferred返回complete,error外部捕获
     */
    jqXHR[i](s[i]);
}

通过一个 for 循环把对应的方法都执行了,具体就是这几个:

  1. jqXHR.success(s.success)  -> jqXHR.done -> jQuery.Callbacks("once memory")
  2. jqXHR.error(s.error)  -> jqXHR.fail -> jQuery.Callbacks("once memory")
  3. jqXHR.complete(s.complete) -> jQuery.Callbacks("once memory").add(s.success

 

我们参考右边 Ajax 的模拟实现代码。

 

任务

?不会了怎么办
||

提问题

写笔记

截图
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最新 点赞
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?