开头引用一段

想起一句话:前端研究,研究个屁~ 的确如此呀。补充下联:前端设计,设计个屁~

前端目前最大的困境是,如 HTML 一样,无论你承不承认,市场上并不太需要 HTML 高手

其实这里引发一个问题:前端的价值究竟是什么?未来应该如何发展?

我个人觉得还是一个核心价值的问题,前端在漂亮的东西都是需要后端的数据支撑的,而且前端的绝大部分问题,其实都需要后端才能解决,就如我开发了三年的混合项目,虽然前端代码有3万行,但是后端一个数据拷贝失败,整个项目都是白搭

当然这里我并非要深入这个话题,只是想表明尽可能的提高自身的价值

从前端的历史变更与发展过程来看,如果拿人类的历史来比喻,从最原始的刀耕火种以HTML静态结构为主的原始社会,到后来带有逻辑处理与服务器混搭交互的的石器时代以及最近几年流行的node.js,MVC,MVVM,Phonegap等衍生而来的东东让前端大跃进式的跳跃进入了一个新的工业时代,不到20年的时间web技术翻天覆地的变化

如今的前端进入了 MV* 时代,同时Ajax也带来了SPA,Node带来了全栈,这些都切实推动着前端往前发展

优秀的前端一方面是完成的效率,另一方面是可维护和可扩展性的提高带来的潜在价值,解放生产力,专注展现与业务逻辑,减少琐碎的兼容处理

如果你使用一面大镜子作为冲浪板会发生什么?或许你会在较短的时间内征服海浪,但是你肯定从内心深处明白,这不是冲浪的正确选择

所以我们不应该只要求自己仅仅停留在API的层次,如果能理解原理深入设计,那么就将会跨上一个新的台阶

 


jQuery.Ajax做了那些事?

我们知道AJAX的底层实现其实是很简单的.抛开IE不说,标准的w3c直接提供了XMLHttpRequest方法

关于AJAX基础请飞机 触碰jQuery:AJAX异步详解

我们主要站在设计的角度理解,如何设计出低耦合高内聚的代码

jQuery对Ajax的处理主要体现在对浏览器兼容,数据的处理及过滤,各种事件的封装上

主要有以下几部分扩展:

提供快捷接口

提供底层接口

提供数据序列化

提供全局Ajax事件处理

具体使用请看API,这里不再重复

 


分析下面一个demo

给document绑定ajaxStart,ajaxComplete回调事件

trigger绑定一个点击事件,发送ajax请求

点击trigger出发点之后,发送一个ajax请求,并且通过complete,done,ajaxStart, ajaxComplete返回状态回调

//全局事件触发
$(document).ajaxStart(function() {
console.log(arguments)
}).ajaxComplete(function() {
$(".log").text("Triggered ajaxComplete handler.");
}); $(".trigger").click(function() {
//发送ajax请求
//
$.ajax({
url: "php.html",
context: document.body,
complete: function() {
console.log(this)
}
}).done(function() {
console.log(this)
});
});

这里实现比较特别的地方

针对ajax提供2种回调方式,内部的complete回调与外部的done回调

全局document上都能捕获到ajax的每一步的回调通知

换句话说,针对ajax的请求,每一步的状态,成功或者失败,我们有3种方式可以获取,但是每一种还是有各自的区别

1 ajax的参数回调

2 基于deferred方式的done回调

3 全局的的自定义事件的回调

 


从设计的层面上来考下,这种事件组合的方式是如何实现?有什么优势?

设计一:

tAjax({
url: "php.html",
complete: function(data) {
console.log(data)
}
})

如果要实现这种接口调用

那么我们就需要封装下代码,把回调通过实参传递

var tAjax = function(config) {
var url = config.url;
var complete = config.complete;
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('post', url);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
complete(xhr.responseText);
}
}
}
xhr.send();
}

这样设计可以看做类似工厂模式的封装,好处不用多说,在工厂模式里面包含了对象的创建等必要的逻辑,客户端根据传参选择动态的实例化相对的处理

对于客户端来去除了具体的依赖,当然tAjax你也可以看作一个外观模式提供的接口,其实就是隐藏了具体的复杂逻辑,提供一个简单的接口,从而降低耦合

 


设计二:

tAjax({
url: "php.html",
complete: function(data) {
console.log(data)
}
}).done(function(data){
console.log(data)
})

在之前加入了一个done链式处理,当然这里done,其实是deferred的一个成功处理通知,如果之前没有接触,大家去了解一下关于deferred的概念

我们知道jQuery实现了链式,实现的原理无法就是返回本身对象的引用

var ajax = tAjax({
url: "php.html",
complete: function(data) {
console.log(data)
}
}) ajax.done(function(){ })

以上是分离的情况下,如果要合并成一条链式处理,只要在上一个方法中返回this即可

所以我们改改

var tAjax = function(config) {

    var doneFn;

    var url      = config.url;
var complete = config.complete;
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('post', url);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
doneFn(xhr.responseText);
complete(xhr.responseText);
}
}
} xhr.send(xhr.responseText); return {
/**
* 返回一个done对象
*/
done: function(ourfn) {
doneFn = ourfn;
}
};
}

我们返回了一个done对象,这里一样要是对象,因为链式的原因,我们看外部指定了内部的done,从而把外部函数给引用到内部的doneFn上 缓存起来

xhr.staturs 成功后一起执行

当然这种设计是有问题的,如果在done之后我在链式就肯定不行,因为对象的引用错了,那么jQuery是如何处理?

 


设计三

提供document对象的全局处理

$(document).ajaxComplete(function() {
console.log('ajax请求成功')
}); tAjax({
url: "php.html",
complete: function(data) {
console.log(data)
}
}).done(function(data){
console.log(data)
})

这里的问题就是把ajax内部的事件,返回给全局捕获了,有点类似css3的全局动画事件

这里的设计其实最简单了因为本身之间没有什么耦合,就是发送一个事件给document即可

jQuery利用了trigger自定义事件触发的

globalEventContext.trigger("ajaxComplete", [jqXHR, s]);

具体每一种实现在后面的都会提到,在这里需要大家有个整体的印象,

 


总结:

通过读阅jQuery.ajax这段api我们可以看到jQuery对ajax的处理做的相当的全面

首先我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

ajax引入了deferred方案,callback方案就是回调函数解决方案,从而处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口

伴随Ajax请求会触发若干事件,我们可以订阅这些事件并在其中处理我们的逻辑。

在jQuery中有两种Ajax事件:局部事件和全局事件。

局部事件(回调函数),在$.ajax()方法的options参数中声明,可以用来设置请求数据和获取、处理响应数据。

全局事件,每次Ajax请求都会触发,它会向DOM中的所有元素广播,你只需为DOM中任意元素bind好全局事件即会触发(若绑定多次,则会依次触发为事件注册的回调函数

除此之外,还提供了一系列的简化接口,比如.load ,还有直接对数据对象序列化的能力,对跨域的处理,contentType的修复等等

深入待续。。。。。

jQuery源码分析系列(30) : Ajax 整体结构的更多相关文章

  1. jQuery源码分析系列(36) : Ajax - 类型转化器

    什么是类型转化器? jQuery支持不同格式的数据返回形式,比如dataType为 xml, json,jsonp,script, or html 但是浏览器的XMLHttpRequest对象对数据的 ...

  2. jQuery源码分析系列(37) : Ajax 总结

    综合前面的分析,我们总结如下3大块: jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求 前置过滤器 jQuery. ajaxPrefilter 请求分发器 jQuery ...

  3. jQuery源码分析系列(31) : Ajax deferred实现

    AJAX的底层实现都是浏览器提供的,所以任何基于api上面的框架或者库,都只是说对于功能的灵活与兼容维护性做出最优的扩展 ajax请求的流程: 1.通过 new XMLHttpRequest 或其它的 ...

  4. jQuery源码分析系列(33) : AJAX中的前置过滤器和请求分发器

    jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求,分别是: 1.前置过滤器 jQuery. ajaxPrefilter 2.请求分发器 jQuery. ajaxTran ...

  5. jQuery源码分析系列(34) : Ajax - 预处理jsonp

    上一章大概讲了前置过滤器和请求分发器的作用,这一章主要是具体分析每种对应的处理方式 $.ajax()调用不同类型的响应,被传递到成功处理函数之前,会经过不同种类的预处理(prefilters). 预处 ...

  6. jQuery源码分析系列(35) : Ajax - jsonp的实现与原理

    ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本 json核心就是:允许用户传递一个callba ...

  7. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  8. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  9. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

随机推荐

  1. 【SAP BO】无法识别账户信息:无法访问CMS。计算机上的CMS由于某个严重错误而停止。(FWM 20031)

    1.系统环境 OS:Windows Server 2008 R2 RDBMS:Oracle 11g R2(Server.Client同时存在) BI:SAP Business Objects 4.2 ...

  2. btrace使用

    btrace使用 目录btracee是btrace的解压目录 btrace/btrace是btrace的项目工程 root@ubuntu:/usr/local/bogon/btrace# tree b ...

  3. python基础05 if选择

    摘要:if语句是用来检查一个条件,如果条件为真(true),我们运行一个语句块(称为IF块),否则(else)运行另一个语句块(else块).else语句是可选的 程序1(将文件保存为if.py): ...

  4. xpath使用

    一.安装(win7 64) 1.安装lxml,pip install lxml 2.如果安装出错,下载lxml-3.5.0b1.win-amd64-py2.7.exe: 地址:http://www.l ...

  5. 【BZOJ】4001: [TJOI2015]概率论

    题意 求节点数为\(n\)的有根树期望的叶子结点数.(\(n \le 10^9\)) 分析 神题就打表找规律.. 题解 方案数就是卡特兰数,$h_0=1, h_n = \sum_{i=0}^{n-1} ...

  6. 软件工程:黄金G点小游戏1.0

    我们要做的是黄金G点小游戏: N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值. ...

  7. HDU 2087  KMP模板题

    1.HDU 2087 2.题意:一个主串,一个子串,求子串在主串里出现了几次. 3.总结:看了题解,还是不太懂.. //#include<iostream>#include<cmat ...

  8. JAVA自定义注解

    在学习使用Spring和MyBatis框架的时候,使用了很多的注解来标注Bean或者数据访问层参数,那么JAVA的注解到底是个东西,作用是什么,又怎样自定义注解呢?这篇文章,即将作出简单易懂的解释. ...

  9. iOS 中自定义 cell,点击cell的时候文字不出现的原因

    解决方案: 在setSelected方法中设置要显示label的背景颜色即可

  10. JSONObject、JSONArray区别

    json,就是一个键对应一个值,超级简单的一对一关系.现在用到的json那可以层层嵌套啊,刚开始接触的时候,确实有种崩溃的赶脚,不想去理,取个数据还那么麻烦.其实,就跟if else语句一样,如果if ...