【问题标题】:Why doesn't Ajax use self-invocation?为什么 Ajax 不使用自调用?
【发布时间】:2012-05-17 23:11:53
【问题描述】:

自调用closure 函数的奇怪语法意味着您实际上是在调用函数本身,因此使其成为self-invoking。下面是一些代码演示:

<!DOCTYPE html>
<html>
    <head>
        <title>
            A Nameless Function that Executes Itself
        </title>
    </head>

    <body onload = "mainMethod();">

        <div id = "here"></div>

        <script type = "text/javascript">

            function mainMethod()
            {
                var here = document.getElementById("here");
                var hello = "Hello World!";

                here.innerHTML = function()
                {
                    return hello + "<br />";
                }(); // WITH method parentheses -- self-invoking

                here.innerHTML += function()
                {
                    return hello;
                }; // withOUT method parentheses
            }
        </script>
    </body>
</html>


...上面的第二个函数 not 执行,因为它缺少结束括号,innerHTML 成为整个函数本身。那么,为什么您的标准 Ajax 语法不以同样的方式使用自调用呢? XMLHttpRequest 似乎以独特的方式处理 onreadystatechange 属性。下面是一个例子:

function getStock()
{
    var req = new XMLHttpRequest();

    var stock = document.getElementById("stock");

    req.onreadystatechange = function()
    {
        if( (req.readyState == 4) && (req.status == 200) )
        {
            // value of stock
            var stockValue = req.responseText;

            stock.innerHTML = stockValue;
        }
    }
    req.open("GET", "randomStockValue.php?random=", true);
    req.send(null);

    setTimeout("getStock()", 1000);
}


注意缺少结束括号...我问这个是因为我想进一步了解 Ajax 语法,以及它到底在做什么。

【问题讨论】:

  • “那么,为什么您的标准 Ajax 语法不以同样的方式使用自调用呢?”我不明白你的意思,onreadystatechange 的做作不使用括号所以它不应该调用自己。
  • ajax 调用可以是同步的也可以是异步的,如果你写 req.open(uri, url, false) ,它将是同步的,你会得到你的股票而不需要超时 getStock()如果请求成功。
  • @camus:getStock 似乎使用setTimeout 只是为了重复调用它,即每隔1s 更新#stock

标签: javascript ajax closures parentheses self-invoking-function


【解决方案1】:

readystatechange 属性包含一个回调函数(或有时称为事件处理函数),将来当某些 ajax 事件发生时,浏览器的 ajax 引擎将多次调用该回调函数。

您不希望它立即执行。您希望将来发生这些特定事件时调用分配给它的函数。您不希望它自动执行。

有关将来某个时间调用的事件侦听器或回调函数的其他示例,请参阅addEventListener()setTimeout() 等方法。

【讨论】:

    【解决方案2】:

    它注册了一个事件监听器。该函数不会立即执行,它(函数对象)只是分配给onreadystatechange 属性。稍后将调用它 - 当 ajax 请求更改其状态时。这类似于 setTimeout 的超时时间未知(并且会被多次调用)。

    【讨论】:

    • 啊,谢谢 - 因为它是一个事件侦听器,所以它不应该是自执行的,而是应该在 ajax 请求更改其状态时调用它......这本质上是什么它是异步的,对吗?此外,它是“类似于具有未知超时的 setTimeout”很有意义,感谢您的帮助。
    • 是的,这是为了让它异步。
    【解决方案3】:

    ajax 调用处理程序没有什么特别之处,您可以为第一个示例编写完全相同的代码,它会执行相同的等待:

          function mainMethod()
                {
                    var here = document.getElementById("here");
                    var hello = "Hello World!";
    
                    here.innerHTML = function()
                    {
                        return hello + "<br />";
                    }(); // WITH method parentheses -- self-invoking
    
                    here.innerHTML += function()
                    {
                        return hello;
                    }; // withOUT method parentheses
                }
    
    document.body.onload = mainmethod ;
    

    您给出了 2 个不共享相同上下文的示例,这就是为什么它们的行为确实不同。

    现在试试

    document.body.onclick = mainmethod ;
    

    在您点击网页之前,您的功能不会执行。 ajax 调用也是如此。

    【讨论】:

      猜你喜欢
      • 2017-12-10
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 2012-01-19
      • 2011-07-19
      • 2018-07-06
      • 1970-01-01
      相关资源
      最近更新 更多