AjaxPro 内部机制探讨
Invoke 函数是核心所在,前面我画的流程图中已经简单地描述了它的主要流程。不过这个函数太重要了,这里还是列出它的全部源码:
2AjaxPro.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 else
28 this.xmlHttp.setRequestHeader("Connection", "close"); // Mozilla Bug #246651
29
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 中的代码就明白了:
2 for(property in source) {
3 destination[property] = source[property];
4 }
5 return destination;
6}
7
哈哈,所谓的“继承”,其实只是个属性拷贝而已。