比如说,在我的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
来解决这个问题,但我想让它保持异步。
非常感谢任何帮助。
答案 0 :(得分:1)
这可能是涉及使用Javascript进行闭包的问题吗?如果在for循环中定义一个函数并在函数内部分配变量,它们将通过成功回调保留其作用域。
备用(更干净/更优雅)的解决方案会将for
循环和函数调用重写为Array.prototype.forEach()(感谢Jaromanda X)
在函数内部,变量是作用域的。以前,每个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);
}
});
});