`
insertyou
  • 浏览: 863589 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

一个基于jQuery ajax和.net httphandler 的超轻异步框架,千行代码完成。

 
阅读更多
  • 背景

  • 我部正在开发的一个新项目,选择了jQuery作为基础的Javascript函数库。同时确定了jQuery提供的ajax系列方法作为异步推拉数据的基础接口。

    使用过ajax方法的同事应该是知道的,ajax方法需要提供一组选型,比如content-typemime-typedataasync等等,这些选项的组合搭配可以构成不同的请求方式,必须理解HTTP的部分协议才能够正确的完成配置。当然,也可以从google上去找配置好的代码片段copy过来用, 关于这种方式的缺陷就不多说了。

  • 我的失误

  • 1. 没有在代码编写之前,规定好如何利用jQueryajax方法。导致开发人员直接把ajax方法的调用写在页面的脚本块内,导致页面内出现了如下所示的代码:

    $.ajax({ type: "post", contentType: "application/json",datatype: "json", async: false, url: "DemoHandler.asmx/GetData",data: "{index:1}", complete: function(e, s) { alert("ok")});

  • 分析现象

  • 上面的代码的意图是通过httppost方法,调用服务端web servicesGetData方法,传入的参数名称为index,值为1 。这是以硬编码方式与服务端达成的强耦合关系的编码方式,隐含了如下的问题:

    1. DemoHandler.asmx文件的路经改变了,就会影响页面内所有这样的代码;

    2. 服务端GetData的方法签名如果变化了,就会影响页面内所有这样的代码;

    3. 如果以后出现了更好的ajax框架,替换的工作量也是如同推倒重来的;

    4. GetData这样的方法如果被其他地方调用,采用的方法是copy一段这样的代码;

    5. 当我们提倡前后台分开的开发的情况下,理论上前台开发人员精通的技术应该是div+cssjs这些,后台开发才关注web services这样的技术。只有这样才能把各自的领域做精、最好。上面所示代码的第一个模板是我提供的,因为我个人扮演了联通前台和后台技术的桥梁角色,但反思起来他是个人行为,却不是团队力量的体现。

    6. 开发人员可以自问一下,contentType: "application/json" 这个选项起到什么作用?为什么DemoHandler.asmx/GetData这样的写法可以成功调入到web services方法内部?为什么data要写成 "{index:1}" 这样的样式?我尝试问了项目组的人,答案都是不知道。很明显,真正和开发有关的只是业务,而不是这些底层协议方面的知识,它是可以对大家屏蔽的。

  • 解决办法

  • 当把存在的问题分析清楚了,答案也就有了。我们为每一个web serivices写一个专门的js文件,它内部封装了一组与web method一致签名的函数。这样页面只通过js方法传参数调用即可,而不再关注那些ajax调用选项的细节。达到了相关概念的逻辑统一封装和管理、一点维护多点使用、不同职责的开发人员关注不同功能这些要求。

    在这件事情的执行上,又出现了一个小插曲。负责写js文件的同学参考了其它网上牛人的js书写风格,也玩起了风靡一时的js花招动态对象、闭包。当然很快就被否定了,其它原因不多讲,只有一点原因需要特别说明:任何编程技巧和技术的使用都要考虑它是否适合团队中的一般水平,如果不适合就要考虑其它办法。闭包显然只是一个技巧而已,不是解决问题的王道。它的引入至少给一般人阅读代码增加了难度,所以要被PASS掉。

    最终还是选择采用大白话式的prototype来声明服务对象的方法。一开始,我写了一个头部的初始化函数,该函数封装好了所有的选项配置信息,以及把服务对象扩展到jQuery体系中去,使开发人员可以按照一致的规格调用服务端函数。后期,其他开发人员只要在文件的尾部按需追加一个个与服务端方法对应的函数即可。

  • 优化与改进

  • 为了利用.net script servicesweb services的扩展,项目组一开始规定后台直接提供web services对客户端进行暴露。这对客户端提交数据没有问题,但对我们使用的某些控件就不太适合了。因为控件要求返回值是一个纯粹的json数据,而script services框架会在输出的json数据外层再包上一个名d的根,这就导致控件无法识别这个数据源。于是项目组通过ashx文件,实现Ihttphandler来手动处理请求。

    很快,服务端工程里多出了10几个ashx文件,因为客户端需要10几种不同的数据请求。每个ashx内部的ProcessRequest方法处理四件大事:1)设置WEB反馈的HTTP头信息;2)处理业务逻辑;3)序列化业务数据为JSON4)把JSON数据写到输出流中。

    这个现象说明了两个问题:1ashx文件的数量会随着应用需求的增多而不断的增多,今后非常难以维护;2)四件事情只有一件是必须每次都做的,即处理业务逻辑,其它事件都是有规律并重复的。

    基于对上述问题,项目组做出了改进,实现一个统一的WEB请求的调度和处理机制,使得同一类的请求可以放在一个ashx文件内完成,并且每个请求直接映射到一个函数来完成,输出、输出、缓存都由这个机制来处理;另外,普通开发人员只需要完成业务逻辑代码即可,其它一概不要关心。

    时间又过了2天,新的问题再此困扰了我。如果服务端增加一个新的方法,客户端的js也要与之匹配的增加一个函数作为调用代理。这样同一语意的函数,就产生了前后台两点维护,这是不合理的。它也是一个机械性的工作,每次都要开发手动来做,这也是不人性的。于是,新的解决方法是当客户端直接请求ashx文件的时候,服务端自动生成相应的客户端代理脚本。这样带来了客户端代码更大的改进,我们只需要将 <script src=”..\xHandler.ashx”>置入页面,一切就OK了。因为自动获得的js脚本会自动初始化客户端服务,后续就可以在页面的任何地方通过例如这样的方法调用服务了: $.net. xHandler.GetData()

    这样改进之后,项目组的开发人员是充满喜悦的,因为他们可以少做很多不必要的事情,可以把代码写的更加整洁,可以让BUG变的更少。从此,我们也把整合jQuery.ajax.net的技术方案固化了下来,以后团队将依赖存在的技术稳定的工作,而不再依赖个人。顺便说一句,在我们写出这些代码的时候,已经考虑过例如ajaxpro.net.NET MVC这样的框架,只是他并不适合我们而已。

    最后,附源码:WebHandler.zip

    分享到:
    评论
    1 楼 月下小人 2011-12-02  
    顶,这才是质的提高,果断顶

    相关推荐

    Global site tag (gtag.js) - Google Analytics