javascript代码实例教程-jQuery源码分析系列(31) : Ajax deferred实现

发布时间:2019-02-02 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-jQuery源码分析系列(31) : Ajax deferred实现脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 AJAX的底层实现都是浏览器提供的,所以任何基于api上面的框架或者库,都只是说对于功能的灵活与兼容维护性做出最优的扩展

 

ajax请求的流程:

 

1、通过 new XMLHttPRequest 或其它的形式(指IE)生成ajax的对象xhr。  

 

2、通过xhr.oPEn(type, url, async, username, password)的形式建立一个连接。 

 

3、通过setRequestHeader设定xhr的请求头部(request header)。  

 

4、通过send(data)请求服务器端的数据。

 

5、执行在xhr上注册的onreadystatechange回调处理返回数据。

 

这几步之中,

 

我们开发者可能会遇到的问题

 

1 跨域

 

2 json的格式

 

3 dataType

 

4 AJAX乱码问题

 

5 页面缓存

 

6 状态的跟踪

 

7 不同平台兼容

 

jQuery主要就是解决上面这问题,之后就在这个基础之上进行扩展

 

 

 

jquery2.0.3版的Ajax部分码大概有1200多行,主要针对ajax的操作进行了一些扩展,使之更加灵活

 

jQuery在1.5中对AJAX模块的重写,增加了几个新的概念

 

AJAX模块提供了三个新的方法用于管理、扩展AJAX请求,分别是:

 

前置过滤器 jQuery. ajaxprefilter

请求分发器 jQuery. ajaxTransport,

类型转换器 ajaxConvert

除此之后还重写了整个异步队列处理,加入了deferred,可以将任务完成的处理方式与任务本身解耦合,使用deferreds对象,多个回调函数可以被绑定在任务完成时执行,甚至可以在任务完成后绑定这些回调函数。这些任务可以是异步的,也可以是同步的。

 

比如

 

1.链式反馈done与fail

 

复制代码

$.ajax({

    url: "script.php",

    type: "POST",

    data: {

        id: menuId

    },

    dataType: "htML"

}).done(function(msg) {

    $("#LOG").html(msg);

}).fail(function(jqXHR, textStatus) {

    alert("Request failed: " + textStatus);

});

复制代码

 

 

2.分离异步与同步处理

 

复制代码

VAR aajax = $.ajax({

    url: "script.php",

    type: "POST",

    data: {

        id: menuId

    },

    dataType: "html"

}).fail(function(jqXHR, textStatus) {

    alert("Request failed: " + textStatus);

});

 

 

//同步还在执行代码,这个函数有可能在AJAX结束前调用

DOSomething()

 

//异步还在等在成功响应

aajax.done(function(msg) {

    $("#log").html(msg);

})

复制代码

不再被限制到只有一个成功,失败或者完成的回调函数了。相反这些随时被添加的回调函数被放置在一个先进先出的队列中。

 

 

 

3.同时执行多个ajax请求

 

复制代码

function ajax1() {

    return $.get('1.htm');

}

 

function ajax2() {

    return $.get('2.htm');

}

 

 

$.when(ajax1(), ajax2())

    .then(function() {

       //成功

    })

    .fail(function() {

       //失败

    });

复制代码

这个比较复杂一点,原理其实就是$.get返回的是一个deferred对象,每个jQuery的AJAX方法返回值都包含一个promise函数,用来跟踪异步请求。Promise函数的返回值是deferred对象的一个只读视图

 

Deferreds通过检测对象中是否在Promise()函数来判断当前对象是否可观察。$.when()会等待所有的AJAX请求结束,然后调用通过 .then(), .fail()注册的回调函数(具体调用哪些回调函数取决于任务的结束状态)。这些回调函数会按照他们的注册顺序执行

 

显而易见,deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口

 

 

 

jqXHR 对象

 

说白了无非就是在ajax的实现逻辑中,把deferred对象给掺进去了,使之整个ajax方法变成了一个deferred对象

 

在ajax方法中返回的是jqXHR一个包装对象,在这个对象里面混入了所有实现方法

 

ajax: function(url, options) {

    //.........

    return jqXHR

}

从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()

 

 

 

 

那么在对包装器jqXHR对象做混入之前,我们要先准备好

 

1 异步队列deferred

 

2 回调队列Callbacks

 

复制代码

// Deferreds

deferred = jQuery.Deferred(),

 

/**

 * 所有的回调队列,不管任何时候增加的回调保证只触发一次

 * @type {[type]}

 */

completeDeferred = jQuery.Callbacks("once memory"),

复制代码

 

 

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

 

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

image

 

此时的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]);

        }

复制代码

jqXHR.success(s.success)  -> jqXHR.done -> jQuery.Callbacks("once memory")

 

jqXHR.error(s.error)  -> jqXHR.fail -> jQuery.Callbacks("once memory")

 

jqXHR.complete(s.complete) -> jQuery.Callbacks("once memory").add(s.success)

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-jQuery源码分析系列(31) : Ajax deferred实现全部内容,希望文章能够帮你解决javascript代码实例教程-jQuery源码分析系列(31) : Ajax deferred实现所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。