• 对onreadystatechange属性的理解


    发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态,XMLHttpRequest对象提供了onreadyStateChange事件实现这一功能。这类似于回调函数的做法。
    onreadyStateChange事件可指定一个事件处理函数来处理XMLHttpRequest对象的执行结果,如:

    ajaxObj=createAjaxObject(); 
    var url="/MyTodoes/FetchText?id="+id;  
    ajaxObj.open("Get",url,true);
    ajaxObj.onreadyStateChange=changeTabCallBack;
    ajaxObj.send(null);

    onreadyStateChange事件是在readyState属性发生改变时触发的,readyState的值表示了当前请求的状态,在事件处理程序中可以根据这个值来进行不同的处理。 readyState有五种可取值

    0:尚未初始化,

    1:正在加载,

    2:加载完毕,

    3:正在处理;

    4:处理完毕。

    一旦readyState属性的值变成了4,就可以从服务器返回的响应数据进行访问了。
    通常在事件中判断readyState的值是在请求完毕时才做处理,如:

    function changeTabCallBack(){
      if(ajaxObj.readyState==4){
         // 下一步验证
      }
    }

    Status存储了服务器端返回的Http请求响应代码,它表示请求的处理结果,常见响应代码的含义如右。
    在Ajax开发中,最常用就是200这个响应码,代码如下:

    function changeTabCallBack(){
      if(ajaxObj.readyState==4){
        if(ajaxObj.status==200){
           // 服务端返回了正确数据,开始响应处理
        }
      }
    }

    Http状态码 含义
    200 请求成功
    202 请求被接受但处理未完成
    400 错误请求
    404 请求资源未找到
    500 内部服务器错误

    在编写Ajax方法的时候,我们经常会写上类似于这样的代码:

    <script type="text/javascript">
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客var xmlHttp;
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客//创建一个XmlHttpRequeset对象
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客function createXMLHttpRequest(){
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客    if(window.ActiveXObject){
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客         xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     }
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客    else if(window.XMLHttpRequest){
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客         xmlHttp = new XMLHttpRequest();
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     }
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客}
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客//开始一个请求
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客function startRequest(){
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客    
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     createXMLHttpRequest();
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     xmlHttp.onreadystatechange = handlestatechange;
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     xmlHttp.open("GET", "SimpleRespose.xml", true);
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     xmlHttp.Send(null);
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客function handlestatechange(){
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客    if(xmlHttp.readyState == 4){//描述一种"已加载"状态;此时,响应已经被完全接收。
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客        if(xmlHttp.status == 200){//200表示成功收到        
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客             alert("The Server Replied with:" + xmlHttp.responseText)
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客         }
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客     }
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客}            
    对on<wbr>readystatechange属性的理解 - 不是小子 - 我的博客</script>

         第一次阅读这段代码的时候,我就感到了一点点不对劲,但是说不出来什么地方不对劲。随着对Ajax代码的进一步了解,这种感觉时刻伴随着我。

        后来,我知道了这种感觉来自于什么地方。

        看看startRequest函数。我们发现xmlHttp.onreadystatechange指向了一个函数,这个函数是在xmlHttpRequest.readyState发生改变的时候触发。我们再来看startRequest函数,想象一下整个请求发送的步骤。现在我们点击一个按钮,触发了一个startRequest函数。函数往下走,第一步是createXmlHttpRequest(),它的作用是创建一个xmlHttpRequest对象,当它完毕的时候,xmlHttpRequest.readyState的值是0(window.alert跟踪得到的),程序继续往下走,xmlHttp.onreadystatechange = handlestatechange,因为状态没有改变(xmlHttpRequest.readyState的值是0),所以不触发函数,紧接着是Open()和Send(),那么,整个函数从头到尾都应该没有触发handlestatechange函数啊,但是为什么出来的结果是正确的呢?

        后来我用window.alert跟踪xmlHttp.readystate的变化,发现于原来它运行的机制是这样的。首先创建一个xmlHttpRequest的对象之后xmlHttp.readyState的值是0了,然后xmlHttp.onreadystatechange = handlestatechange没有运行。紧接着是open(),这个函数发生了之后xmlHttp.readyState的值是1了,那么就会有一个断点在Open()函数处断开,保留现场,紧接着又返回到xmlHttp.onreadystatechange = handlestatechange运行,然后再执行Send()函数,这个函数发生了之后xmlHttp.readyState的值是2了,接着又返回到xmlHttp.onreadystatechange = handlestatechange运行。以此类推。

        浏览器因为不能真正地像面向对象那么编程,所以找了个折衷的办法,但是这个办法看起来不伦不类,想了半天,再跟一个同学一起讨论,才得出这样的一个结果。

    onreadystatechange -----设置为指向handlestatechange的函数的指针(比较难理解些)

    函数是具有执行特定功能的子程序,编译后,它的执行代码分配在代码段,而其参数及变量则在堆栈段,因而主程序调用函数时,实际上就是将程序执行地址转移为函数在代码段的入口地址去执行,即每个函数都有一个在代码段的确定入口地址,依此程序执行,当遇到返回指令时(表示该程序结束),程序便返回到该函数调用者的断点程序处,又继续执行,既然函数有确定的入口地址(实际上函数名就

    代表了它的入口地址),因而可以用指针指向它,这个指针又称为函数指针
  • 相关阅读:
    Job 失败了怎么办?- 每天5分钟玩转 Docker 容器技术(133)
    用 k8s 运行一次性任务
    运行自己的 DaemonSet
    查看内核页表kernel_page_tables (aarch32)
    Linux内存管理学习3 —— head.S中的段页表的建立
    Linux内存管理学习2 —— head.S中的段页表的建立
    Linux内存管理学习1 —— head.S中的段页表的建立
    阅读Linux内核源码时建立tags索引
    在TQ2440上运行perf,生成Flame Graph
    Linux驱动开发——指针和错误值
  • 原文地址:https://www.cnblogs.com/douglasvegas/p/4770504.html
Copyright © 2020-2023  润新知