我已经介绍了Client-Callback技术,那么让我们来探讨一下Client-Callback技术怎样实现异步刷新吧(实现原理)。正所谓"知其然,知其所以然"。 运行前一篇文章的(http://blog.programfan.com/article.asp?id=29426)例子,用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函数。 最后,如果大家有什么好的看法可以反馈给我。

评论