关闭

Client端异步Callback实现的原理

926人阅读 评论(0) 收藏 举报

我已经介绍了Client-Callback技术,那么让我们来探讨一下Client-Callback技术怎样实现异步刷新吧(实现原理)。正所谓"知其然,知其所以然"。

运行前一篇文章的(http://blog.csdn.net/goalbell/archive/2007/09/16/1787213.aspx)例子,用firebug调试并打开查看一下WebResource.axd?d=23ERqfzqTJs6_Rg9n1je_Q2&t=633249794114687500。你会发现里面大有文章,呵呵!微软已经帮你封装好实现异步所需要的技术了,即是XmlHttpRequest对象。从firebug里面的js代码总共有537行,实现的技术大部分围绕XmlHttpRequest对象以及Dom技术。下面分析核心代码(core)的实现过程吧。Let's Start!

下面的一段代码取自WebForm_DoCallback的函数里面:

 var xmlRequest,e;
 try {
  xmlRequest = new XMLHttpRequest();
}
catch(e) {
try {
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
 }
catch(e) {
}
}
 var setRequestHeaderMethodExists = true;
try {
 setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
}
catch(e) {}
 var callback = new Object();
callback.eventCallback = eventCallback;
 callback.context = context;
 callback.errorCallback = errorCallback;
callback.async = useAsync;
 var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);
if (!useAsync) {
if (__synchronousCallBackIndex != -1) {
 __pendingCallbacks[__synchronousCallBackIndex] = null;
 }
 __synchronousCallBackIndex = callbackIndex;
 }
 if (setRequestHeaderMethodExists) {
 xmlRequest.onreadystatechange = WebForm_CallbackComplete;
 callback.xmlRequest = xmlRequest;
 xmlRequest.open("POST", theForm.action, true);
 xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send(postData);
return;
}

分析一下:

             首先实例化一个兼容三种浏览器(IE、FF、SF)的XmlHttpRequest对象,接着调用javascript内置的Object类来建立一个callback构造函数,该构造函数总共有四个属性。至于Callback构造函数有什么用呢?接下来这一句callback.xmlRequest=xmlRequest可以看到,将XmlHttpRequest的实例赋给了callback的属性了。最后XmlHttpRequest的实例(xmlRequest),即xmlRequest的回调方法onreadystatechange指向了WebForm_CallbackComplete,而WebForm_CallbackComplete这个函数干什么的呢?下面会分析的;xmlRequest向服务器发送请求,theForm.action怎样获得的呢?她是通过WebForm_DoPostBackWithOptions函数来获得的。由于xmlRequest是用"POST"方法向服务器请求的,所以要标明请求的头格式以及发送的参数。好了分析完上面的代码之后,我们一起来看一下WebForm_CallbackComplete究竟做了什么呢?

下面的是完整的函数示例:

function WebForm_CallbackComplete() {
 for (i = 0; i < __pendingCallbacks.length; i++) {
 callbackObject = __pendingCallbacks[i];
 if (callbackObject && callbackObject.xmlRequest && (callbackObject.xmlRequest.readyState == 4)) {
 WebForm_ExecuteCallback(callbackObject);
 if (!__pendingCallbacks[i].async) {
 __synchronousCallBackIndex = -1;
 }
 __pendingCallbacks[i] = null;
var callbackFrameID = "__CALLBACKFRAME" + i;
var xmlRequestFrame = document.getElementById(callbackFrameID);
if (xmlRequestFrame) {
 xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
 }
 }
 }

我们看一下,_pendingCallbacks怎样来的,var __pendingCallbacks = new Array();原来_pendingCallbacks是一个数组变量来的,其实从循环也可以猜到了。接着就将它赋给一个callback对象了,其实callback对象上面已经实例化了(上面那个callback构造函数)。最后就是判断xmlRequest的状态码来执行WebForm_ExecuteCallback函数。

最后,如果大家有什么好的看法可以反馈给我。

 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5099次
    • 积分:99
    • 等级:
    • 排名:千里之外
    • 原创:5篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档