【问题标题】:Why closures are needed here for calling a XMLHttpRequest function in loops?为什么在循环中调用 XMLHttpRequest 函数时需要闭包?
【发布时间】:2016-06-28 18:38:23
【问题描述】:

我对这个网站很陌生。在处理在 for 循环中复制的 XMLHttpRequest 时,我有一个问题,如下所示:

我不明白以下两段代码的区别:

function changeForm(i) {
    if (selection[i-1] != 0) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("box"+i).innerHTML = xmlhttp.responseText;
            }
        };
        xmlhttp.open("POST", "fetchLineChoice_addData.php", true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.send("index="+i+"&lc="+selection[i-1]);
    } else {
        document.getElementById("box"+i).innerHTML = "";
    }
}

for (var i = 1 ; i < 4 ; i++) {
    changeForm(i);
}

for (var i = 1 ; i < 4 ; i++) {
    if (selection[i-1] != 0) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("box"+i).innerHTML = xmlhttp.responseText;
            }
        };
        xmlhttp.open("POST", "fetchLineChoice_addData.php", true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.send("index="+i+"&lc="+selection[i-1]);
    } else {
        document.getElementById("box"+i).innerHTML = "";
    }
}

我真的不知道为什么第一个有效,但第二个无效。我曾尝试在网上搜索有关 closures 并想出了这两个:

Calling a XMLHttpRequest continuously

JavaScript closure inside loops – simple practical example

从第二个问题中提到,函数绑定到函数外的一个变量i。我想知道对于第二个代码块(不起作用),我想知道为什么在 i 的值再次增加之前 for 循环中的内容没有完全执行?两段代码执行时的流程是怎样的?

非常感谢!

【问题讨论】:

  • 您链接到的第二个问题详细解释了这个问题。您到底从它的解释中不明白什么? “嗯,问题是变量 i,在你的每个匿名函数中,都绑定到函数外的同一个变量。”所有的回调,将使用相同的i if您不会为每个迭代创建单独的范围,以便每个迭代都有自己的i
  • 实际上,我对正在迭代的函数中变量范围的概念感到很困惑。那么是不是循环里面的代码块会被执行,但是i的值会独立改变,没有完成整个过程?
  • 回调是异步的,稍后会发生。当它发生时,循环已经完成,i 是最终值。

标签: javascript ajax xmlhttprequest closures


【解决方案1】:

第一个有效,因为“i”的值没有被覆盖。它被“关闭”并且在整个执行过程中保持不变。

在第二个示例中,迭代产生了 XMLHttpRequest,但“i”的全局值发生了变化。到请求完成时,它不再指向您期望的“i”值。

【讨论】:

    猜你喜欢
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    相关资源
    最近更新 更多