【问题标题】:AJAX request no longer pointing to correct variable in success callback methodAJAX 请求不再指向成功回调方法中的正确变量
【发布时间】:2017-02-25 00:18:00
【问题描述】:

例如,在我的 HTML 文件中,我的表格中有以下表格行,其中 {{ }} 只是变量:

<tr id="{{ object.id }}">
    <td class="name">{{ object.name }}</td>
</tr>
<tr id="{{ object.id }}">
    <td class="name">{{ object.name }}</td>
</tr>

然后在我的 JavaScript 文件中,我有以下代码:

var rows = document.getElementsByTagName("tr"); 

for (var r = 0; r < rows.length; r++){
        var tr = rows[r];
        var id = tr.id;

        $.ajax({
            url: "/some-link/" + id,
            success: function(some_json){
                some_json = JSON.parse(some_json);
                var td = document.createElement("td");
                td.innerHTML = some_json;

                //Problem is the following tr is referring to the last tr in the for loop by the time the AJAX request is complete
                tr.appendChild(td);
            }
        });
    }

我得到的结果是:

<tr id="{{ object.id }}">
    <td class="name">{{ object.name }}</td>
</tr>
<tr id="{{ object.id }}">
    <td class="name">{{ object.name }}</td>
    <td>SomeJSON from when rows was 0 in the for loop</td>
    <td>SomeJSON from when rows was 1 in the for loop</td>
</tr>

但是,我的预期结果是:

<tr id="{{ object.id }}">
    <td class="name">{{ object.name }}</td>
    <td>SomeJSON from when rows was 0 in the for loop</td>
</tr>
<tr id="{{ object.id }}">
    <td class="name">{{ object.name }}</td>
    <td>SomeJSON from when rows was 1 in the for loop</td>
</tr>

我知道我可以通过添加到 AJAX 请求 async: false 来解决此问题,但我想保持异步。

任何帮助将不胜感激。

【问题讨论】:

  • 你试过把for (var rows = 0; rows &lt; tableRows.length; rows++){ var tr = tableRows[rows];改成for (var i = 0; i &lt; rows.length; rows++){ var tr = rows[i];吗?似乎这就是你想要做的。如果这不起作用,请发布您的所有代码 - tableRows 不在您的代码中。
  • 因为$.ajax 是异步的,所以在调用success 时,所有成功函数的tr 将是tableRows[tableRows.length - 1]
  • @MichaelCoker - 为什么更改变量名会有所不同?
  • @JaromandaX rows 都是 tr 的,然后 OP 将其用作循环的计数器,但引用了代码中不存在的 tableRows
  • 对不起,误读了问题中的代码:p

标签: javascript html ajax flask


【解决方案1】:

这可能是涉及 Javascript 闭包的问题吗?如果你在 for 循环内定义一个函数并在函数内分配变量,它们将通过成功回调保留其范围。

另一种(更简洁/更优雅)的解决方案是将for 循环和函数调用重写为Array.prototype.forEach()(感谢Jaromanda X

We are using [] as a shorthand for accessing the Array prototype, and using .call in order to create the scoped function

在函数内部,变量是作用域的。以前,每个 ajax 成功回调都引用同一个变量(这是异步请求返回时的变量)

[].forEach.call(rows, function(tr) { 
        var id = tr.id;

        $.ajax({
            url: "/some-link/" + id,
            success: function(some_json){
                some_json = JSON.parse(some_json);
                var td = document.createElement("td");
                td.innerHTML = some_json;

                tr.appendChild(td);
            }
        });

});

【讨论】:

  • 一个更干净的解决方案是将 for 循环替换为 [].forEach.call(tableRows, function(tr) { ... });
  • 好主意,我刚开始长途跋涉回家,大约一个小时后将进行编辑,非常感谢!
  • @Hodrobond 嘿我已经编辑了代码,当我试图让代码更容易从我的实际代码中理解时,我在变量名上犯了一些错误。请你更新你的答案
  • 当然,给我一个小时左右,我会回到电脑前:)
  • @Hodrobond 您的解决方案确实有效,谢谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多