Hello World
Spiga

深入Atlas系列:客户端网络访问基础结构(下) - WebRequestExecutor和XMLHttpExecutor

2006-10-29 05:10 by 老赵, 3400 visits
  正如前一篇文章所说的那样,WebRequestExecutor是客户端网络访问的基础结构的唯一扩展点,而XMLHttpExecutor是其默认实现。在ASP.NET AJAX中,开发人员能够将自定义的WebRequestExecutor子类设为默认的Executor,也可以为某一个WebRequest指定一个特定的Executor。虽然一般来说XMLHttpExecutor已经足够大多数应用,但是既然ASP.NET AJAX提供了这个功能,我们也根据默认的类进行一下这方面的学习。


WebRequestExecutor

在ASP.NET AJAX客户端脚本中,Sys.Net.WebRequestExecutor是一个抽象类,它有以下成员:
  • webRequest只读属性:这个属性已经在Sys.Net.WebRequestExecutor得到定义,一般不用去关心它。
  • started只读属性:抽象属性,表明该Executor是否已经开始执行了(或执行过了)。
  • responseAvailable只读属性:抽象属性,表明该Executor是否已经得到response了。
  • timeOut只读属性:抽象属性,表明该Executor是否已经超时。
  • aborted只读属性:抽象属性,表明该Executor是否已经被取消。
  • responseData只读属性:抽象属性,返回字符串形式的response内容。
  • statusCode只读属性:抽象属性,返回请求结果的状态代码。
  • statusText只读属性:抽象属性,返回字符串形式表示的请求结果状态。
  • xml只读属性:抽象属性,返回xml形式的response内容。
  • object只读属性:这个属性已经在Sys.Net.WebRequestExecutor得到定义,用于返回一个表请求明结果的对象。
  • executeRequest方法:抽象方法,用于执行当前的请求。
  • abort方法:抽象方法,用于取消当前的请求。
  • getResponseHeader方法:抽象方法,通过指定的name,从请求结果的Header中获得对应的值。
  • getAllResponseHeaders方法:抽象方法,返回字符串形式表示的所有的Header信息。
  大多数朋友们应该可以发现上面的许多方法或属性都和XMLHttpRequest对象的方法或属性一一对应,我对于上面这些方法和属性的理解也是如此。但是事实上,大部分的方法和属性由于都是抽象的,因此从实现上完全可以由开发人员自由发挥。还有关键的一点就是返回值的类型也可以改变。例如,在XMLHttpRequest对象中,getAllResponseHeaders方法的作用是返回一个字符串,用来表示整个Response的Header,如果我们在开发自定义的WebRequestExecutor时完全可以使其返回一个对象,这样从使用角度来说也会比较方便。

WebRequestExecutor很简单,接下来我们从ASP.NET AJAX中的默认实现来自己看一下具体的实现方式。


XMLHttpExecutor

大部分的属性与方法的意义实在不大。我们就来看几个关键方法的实现吧,它们会涉及到WebRequestExecutor的状态,即使我们的实现不同,这些状态一般来说还是保持统一的。

1、构造函数

构造函数的作用其实只是初始化所有的状态,它们分别是:
  • responseAvailable属性设为false
  • timedOut属性设为false
  • aborted属性设为false
  • started属性设为false

2、executeRequest方法

调用这个方法就会构造一个XMLHttpRequest对象,并发起一个请求。代码如下:
Sys.Net.XMLHttpRequest.executeRequest方法

可以发现,在这个方法被调用之后,started属性被设为了true,以此避免同一个Executor被执行两次。

3、_onReadyStateChange方法

这个方法是XMLHttpRequest对象的onreadystatechange回调函数。代码如下:
_onReadyStateChange方法

在这个方法里,只会判断XMLHttpRequest对象的readyState的值,等于4则表示收到了回复,已经执行完毕了,然后进入其他逻辑。这个和“标准”的AJAX逻辑似乎有些不同,这是因为在ASP.NET AJAX中的WebRequestExecutor中,会将判断response结果的逻辑交由其它代码完成。在Executor中只需表示“Complete”即可,其余的,都交给别人去吧。

在这个方法中,responseAvailable被设为了true,表示已经得到了Response——其实在ASP.NET AJAX这部分模型中,这个Response对象就是当前的WebRequestExectuor自身。

4、_onTimeout方法

timeout触发器会调用这个方法。代码如下:
_timeout方法

当一个请求超时的时候,需要调用XMLHttpRequest.abort方法来取消这个请求。同时,timeout属性被设为了true。

5、abort方法

这个方法负责取消一个请求。代码如下:
abort方法

这个方法会调用XMLHttpRequest对象的abort方法来取消这个请求,并且将aborted属性设为true。


上面就是XMLHttpExecutor类的“分析”了,其实代码都非常简单(有时候我会想,难道我是为了系列文章内容的完整性才写这些吗?它们的质量有没有到一定的标准?它们有一定的存在价值吗?)。我们来思考一个问题,到底什么时候我们需要自定义一个Executor?我们需要满足一个什么样的功能?在实际应用中XMLHttpRequest的功能还不够吗?写一个IFrameExecutor?个人认为,一般来说,如果真的要对WebRequestExecutor进行扩展的话,估计也是在XMLHttpExecutor的基础上进行扩展了,我们可以依靠对于XMLHttpExecutor的继承或者封装附加一些新的功能,例如统一的身份验证和异常处理等等。在与这篇“分析”相对应的“示例”中,我将提供一个继承于XMLHttpExecutor的类,它能够将页面上所有请求的全部或部分信息输出在页面上,方便开发人员跟踪与调试。当然,这只是一个在开发过程中的应用。至于完整定义一个WebRequestExecutor……那么为客户端的单元测试定义一个WebRequestExecutor的mock对象吧。

感觉“深入Atlas系列”的文章有些难写了,有时候我也会忽然不知道应该写什么。希望大家对我的文章多提一些意见和建议。谢谢大家!
Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

8 条回复

  1. 老赵
    admin
    链接

    老赵 2006-10-29 05:33:00

    这篇文章……真感觉没有什么价值……

  2. 小蜗牛
    *.*.*.*
    链接

    小蜗牛 2006-10-29 08:53:00

    sigh,就算是善始善终吧。

  3. cathsfz
    *.*.*.*
    链接

    cathsfz 2006-10-29 14:17:00

    嗯……这部分的代码解释了意义确实不太大,因为不容易扩展,并且理解了也难以启发什么新的使用技巧。

    我想能不能做一个BatchExecutor,把Beta1取消了的BatchCall功能补回去。BatchExecutor应该容易做,反正就是由收到第一个请求开始,等若干秒或者等若干个请求,然后将请求合并并调用XMLHttpExecutor完成任务。当然,服务器端也要添加一个IHttpHandler,将请求解包并发送到正确的处理器。

    其实batch是一个很有用的功能,而且配置既可使用,真的非常方便。我用July CTP做了一个类似Google Calendar的个人月历(“个人”的意思是不涉及Membership),每翻一页就会调用一次Web Service来同步新翻到这页的数据,如果用户连续按几次翻页那么batch就能够一次性完成几页的同步,效率高很多。

  4. 老赵
    admin
    链接

    老赵 2006-10-29 14:41:00

    @cathsfz
    batch的确是个可用的东西,如果需要的话可以实现一个,呵呵。不过您说的这个情况似乎也不是个典型的batch call的案例,它更适合只保留最后一次调用的这个做法,因为之前的web services call不会产生价值了。

  5. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2006-11-30 22:31:00

    没信心了,和你们差距太大了,你们写,我看都看不懂。

  6. 老赵
    admin
    链接

    老赵 2006-11-30 22:39:00

    @蛙蛙池塘
    术业有专攻。:)

  7. 共同学习,共同进步
    *.*.*.*
    链接

    共同学习,共同进步 2007-03-20 23:03:00

    老赵哥,相信我多看几遍,就可以领悟一些,谢谢您的分享。注意身体呀,呵呵

  8. 老赵
    admin
    链接

    老赵 2007-03-20 23:09:00

    @共同学习,共同进步
    这部分在ASP.NET AJAX中几乎没有什么变化,呵呵。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我