`

[转]从“异步消息传递--回调机制”理解ICallbackEventHandler 的AJAX实现

阅读更多
http://mochou123456.blog.163.com/blog/static/46057646200941423625216/

关于这个实现,网上相关的资料有很多,也好像讲得很条理,清楚。通过那些资料本人也在自己的系统中实现了地图的 AJAX 页面的”无回发回调”。但是对于它真正的机制我却始终知其一而不知其二。
也许是本人基础太差,究其原因,就是不知道贯穿始终的“客户端回调”究竟是指什么。
记得在3D编程的遍历中也有“回调”这概念, 当时就有点稀里糊涂不能理解。而实际上经过查资料,才知道“回调”是Win线程里一种重要的消息机制。所以事实上理解Dot Net中ICallbackEventHandler的AjAX回调,关键还是在理解“回调”是什么,意味着什么。
理解了这一点的,对于实现已经封装了很多细节的ICallbackEventHandler 接口来说,也只是一个“回调函数”的调用过程。
1.什么是回调
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础(引用自网络)




2、回调函数
回调函数,就是由你自己写的。你需要调用另外一个函数,而这个函数的其中一个参数,就是你的这个回调函数名。这样,系统在必要的时候,就会调用你写的回调函数,这样你就可以在回调函数里完成你要做的事。例如:模块A有一个函数foo,它向模块B传递foo的地址,然后在B里面发生某种事件(event)时,通过从A里面传递过来的foo的地址调用foo,通知A发生了什么事情,让A作出相应反应。 那么我们就把foo称为回调函数。
(参考http://www.yuanma.org/data/2006/0605/article_641.htm)
3、ICallbackEventHandler实现模式AjAX的一般模式
Dot Net 2.0中ICallbackEventHandler接口封装了从客户端的JavaScript通过XmlHttp方式调用服务器端的代码,所以只要在页面中实现了这个接口,便可以无需要使用其它的Ajax框架或是自己动手写XmlHttp请求这两种方式实现异步回调,可以避免回发过程中带来的页面刷新,这样不但减少了页面刷新的延时而且服务端无需处理每次回发的大量视图状态(View State)信息,应用程序的整体性能会有很大的提高。
ICallbackEventHandler 接口。继承这个接口需要实现两个方法RaiseCallbackEvent和GetCallbackResult,其中,RaiseCallbackEvent用来处理客户端提交的请求,RaiseCallbackEvente有一个string类型的参数,是客户端提交到服务器端的参数。而GetCallbackResult方法则负责把服务器端的处理结果返回到客户端。
为了向服务器页发送回调和接收结果这两个功能,可以在客户端定义两个脚本函数来实现用ClientScriptManager类的GetCallbackEventReference方法在客户端注册一个向服务器端发送请求的函数。Page.ClientScript获得页面的ClientScriptManager引用,GetCallbackEventReference注册发送回调请求的函数。
在客户端注册了一个向服务器发送请求的函数,所以一般可以在页面的按钮单击事件或其它事件触发时,向服务器发出请求
比如,在页面的html 中有
<input type="button" id="btnSubmit" value="提交" onclick="CallServer(txtEnter,lblShow)"/>
页面的Javascript中
  function CallServer(inputcontrl,context)
    {
context.innerHTML="加载中……";
var arg=inputcontrl.value;
<%=ClientScript.GetCallbackEventReference(this,"arg","ReceiveServerData","context",true)%>
}
 
<%=ClientScript.GetCallbackEventReference(this,"arg","ReceiveServerData","context",true)%>

向服务器发出了请求,让服务器发送回调,所以实际上”发送回调”是服务器端执行的。这个语句也可以在后台页面加载时注册,保存在一个结果,则在调试的时候,我们可以看到执行这语句实际上执行一个这样的字符串:
WebForm_DoCallback('__Page',arg,ReceiveServerData,context,null,true)。
到这里,就可与上面提到的“回调函数“联系起来了。
ReceiveServerData实际上就是一个回调函数,根据以上对回调函数的定义,ReceiveServerData是回调函数,是我们自己写的,也就是说我们自己定义的,我们调用 WebForm_DoCallback这个函数,这个函数中的一个参数是ReceiveServerData。“系统在必要的时候,就会调用你写的回调函数”,那么什么时候调用ReceiveServerData这一函数呢。IcallbackEventHandler接口中的会在RaiseCallbackEvent方法处理结束后,将结果返回,然后触发这一函数,调用ReceiveServerData,我们在ReceiveServerData我们可以实现想要的效果。

总结如下:




至于Dot net在哪里触发了RaiseCallbackEvent,回传结果在哪里处理成html形式等问题,则是里面封装的细节,这个我也不清楚,希望懂的朋友留言指教。
一个简单的可执行例子
参考:http://www.sina.com.cn
  • 大小: 18.3 KB
  • 大小: 3.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics