【问题标题】:Pass arguments into ajax onreadystatechange callback?将参数传递给ajax onreadystatechange回调?
【发布时间】:2011-12-20 22:13:48
【问题描述】:

将参数传递给匿名 onreadystatechange 回调的普通纯 javascript(即不是 JQuery)方式是什么?

例如:

function doRequest(){
    /* Get an XMLHttpRequest in a platform independent way */    
    var xhttp = getXmlHttpRequestObject(); 

    var msg="show this message when done"; /* another variable to pass into callback */

     /* How do I pass 'msg' and 'xhttp' into this anonymous function as locals
       named 'x' and 'm'??? */
    xhttp.onreadychangestate=function(x,m)
    {
       if( x.readyState == 4 )
       {
           alert(m);
       }
    }
    /* do the open() and send() calls here.... */
}

【问题讨论】:

    标签: javascript ajax


    【解决方案1】:

    Javascript 支持闭包,因此您编写的匿名函数将能够从封闭的doRequest() 范围访问xhttpmsg

    如果想显式执行此操作(例如,如果您想在代码中的其他位置定义回调函数并重用它),您可以创建一个创建回调的函数。这也允许您使用不同的名称(如xm)对变量进行别名访问:

    function createCallback(x, m) {
        return function() {
            /* Do whatever */
        };
    }
    

    然后在doRequest(),做xhttp.onreadystatechange = createCallback(xhttp, msg);

    如果您只想“重命名”变量,则可以内联匿名:

    xhttp.onreadystatechange = (function(x, m) {
        return function() {
            /* Do stuff */
        }
    })(xhttp, msg);
    

    【讨论】:

    • 谢谢。这个答案促使我学习了更多关于 Javascript 的知识。我真正需要知道的是闭包是如何工作的。
    • http.onreadystatechange = function(){ var xmlHttp = this; if(xmlHttp.status == 200){ console.log("我们知道了!"); } };
    【解决方案2】:

    上述答案的一部分对我不起作用。首先,对于没有参数的单独回调函数:

     xhttp.onreadystatechange = callBack;   //works; the function's NAME is required
    

    现在假设callBack函数被修改为接收一些参数:

     xhttp.onreadystatechange = callBack(x,m); //didn't work, and didn't know why
     xhttp.onreadystatechange = createCallback(xhttp,msg); //bad part of above Answer
    

    但是,在 StackOverflow 的其他地方,有人解释说这与需要为 onreadystatechange 分配“函数引用”而不是“函数调用”有关(就像上面的 NAME 是函数引用),并发布了一个解决方案:

     xhttp.onreadystatechange = function(){callBack(x,m);}; //works
    

    我来这里是为了向其他答案添加一些内容,但现在找不到。所以我不妨在这里添加它。在我自己的代码中,我同时使用了局部变量和全局变量,并发现了一些似乎无法正常工作的东西,但现在我知道实际发生了什么,警告词似乎是合适的。假设“g”是一个全局变量:

     xhttp.onreadystatechange = function(){callBack(x,g);};//anonymous function works
    

    函数引用在某个时间点(T0)分配给onreadystatechange,callBack函数在不同的时间点(T1)被调用。嗯,全局变量“g”在 T1 的值是传递给回调函数的值,而不是在 T0 分配函数引用时的“g”值。不要让这个咬你喜欢它咬我! (局部变量一般不存在这个问题,因为它们通常在 T1 时超出范围,因此 JavaScript 在设置匿名函数的参数值时必须使用它们在 T0 时的现有值。)

    【讨论】:

      【解决方案3】:

      永远不会太晚! :-)

      不必使用 xhttp.onreadystatechange 中的参数传递数据,这有点复杂,只需将属性添加到 xhr 对象本身即可。

      例如:

      var m = "Hello!";
      var xhttp = new XMLHttpRequest();
      xhttp.m = m;
      xhttp.onreadystatechange = function()
      {
          var x, m;
          x = this;
          m = x.m;
          if ((x.readyState == 4) && (x.status == 200))
          {
              alert(m);
          }
      };
      // ...
      

      【讨论】:

      • 这对我有用。我将回调函数添加到新的 XMLHttpRequest。所以要清楚。说“myXMLHttpRequest.anythingIWant = 任何东西;”是完全安全的。它会记住那个值吗?
      • @Joe C 是的,只要“myXMLHttpRequest”存在,“myXMLHttpRequest.anythingIWant”的值就是“anything”,包括回调函数内部。
      • 这对我有用。而不是这个,直接使用变量 xhr.value = response;而在onreadystatechange函数里面,通过xhr.value访问它
      猜你喜欢
      • 2016-12-09
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 2018-04-29
      • 1970-01-01
      相关资源
      最近更新 更多