AjaxPro 内部机制探讨
Invoke 函数是核心所在,前面我画的流程图中已经简单地描述了它的主要流程。不过这个函数太重要了,这里还是列出它的全部源码:
AjaxPro.Request = Class.create();2

AjaxPro.Request.prototype = (new AjaxPro.Base()).extend(
{3

invoke: function(method, data, callback)
{4
var async = typeof callback == "function" && callback != AjaxPro.noOperation;5
var json = AjaxPro.toJSON(data) + "\r\n";6

7
if(AjaxPro.cryptProvider != null)8
json = AjaxPro.cryptProvider.encrypt(json);9

10
this.callback = callback;11

12

if(async)
{13
this.xmlHttp.onreadystatechange = this.doStateChange.bind(this);14
if(typeof this.onLoading == "function") this.onLoading(true);15
}16
17
this.xmlHttp.open("POST", this.url, async);18
this.xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");19
this.xmlHttp.setRequestHeader("Content-Length", json.length);20
this.xmlHttp.setRequestHeader("Ajax-method", method);21
22
if(AjaxPro.token != null && AjaxPro.token.length > 0)23
this.xmlHttp.setRequestHeader("Ajax-token", AjaxPro.token);24

25
if(MS.Browser.isIE)26
this.xmlHttp.setRequestHeader("Accept-Encoding", "gzip, deflate");27
else28
this.xmlHttp.setRequestHeader("Connection", "close"); // Mozilla Bug #24665129

30
if(this.onTimeout != null && typeof this.onTimeout == "function")31
this.timeoutTimer = setTimeout(this.timeout.bind(this), this.timeoutPeriod);32

33
this.xmlHttp.send(json);34
35
json = null;36
data = null;37
delete json;38
delete data;39
40

if(!async)
{41
return this.createResponse();42
}43
44
return true; 45
}46
});47

嗯,相当复杂啊。我们慢慢地看。
AjaxPro.Request 类当然不是只有 Invoke 一个函数,这里省去了其它函数。嗯,我们看到,AjaxPro.Request 也是从 AjaxPro.Base “继承”下来的。
第4行的 async,字面上理解就是指异步,这一行什么意思?嗯,如果传进来的 callback 类型是函数,并且不是无操作,那就认为是异步的。
第5行的 json,它可是相当重要啊。这里调用了 AjaxPro.toJSON 方法把传进来的数据进行了某种编码,本例中这个数据当然就是从 doTest1_next 一路传进来的 TextBox 里我们输入的字符串值了,这个函数的实现,本文也不再列出,可以参见 core.ashx 文件。
接下来第7到8行,如果提供了加密,那么就对 json 进行加密。这个好理解。
第12到15行,如果是异步的,那么这里将 doStateChange 函数绑定到 onreadystatechange 事件上去。嗯,这里的绑定其实也是在 core.ashx 文件里声明的一个方法,本文不再阐述它的实现了,大家有兴趣,可以自己去看。绑定完成后,当服务端完成操作后,doStateChange 函数会被调用,这时可以进行更改页面的工作。此外,这里还检测了一下 onLoading 事件。
第17行到第33行可谓核心代码,我们知道 Ajax 就是使用的 XMLHttpRequest 来完成无刷新页面的。这里我们可看到 this.xmlHttp 被用来进行了请求封装。其中值得我们注意的,Content-Length 使用的 json.length,Ajax-method 则使用的就是传进来的 AjaxMethod 方法名称,本例中为 EchoInput。第30、31行设置了超时处理,当然了,页面不能死等嘛。第33行则将 json 发送到服务端。
接下来的第41行,我们看到如果不是异步操作的话,此处将直接调用 createResponse 函数获得响应。那如果是异步操作呢?记得我们设置了 doStateChange 吧?异步的返回处理就是它的事了。createResponse 函数后面再介绍。
六、解释“继承”
前面我们好几次看到貌似继承。当然它们都仅仅是貌似而已。看看以下 core.ashx 中的代码就明白了:

Object.extend = function(destination, source)
{2

for(property in source)
{3
destination[property] = source[property];4
}5
return destination;6
}7

哈哈,所谓的“继承”,其实只是个属性拷贝而已。