AJAX 请求不再指向成功回调方法中的正确变量
AJAX request no longer pointing to correct variable in success callback method
例如,在我的 HTML 文件中,我在 table 中有以下 table 行,其中 {{ }} 只是变量:
<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
但我想让它保持异步。
任何帮助将不胜感激。
这可能是涉及 Javascript 闭包的问题吗?如果您在 for 循环内定义一个函数并在函数内分配变量,它们将通过成功回调保留其范围。
另一种(cleaner/more 优雅)解决方案会将 for
循环和函数调用重写为 Array.prototype.forEach() (thanks )
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);
}
});
});
例如,在我的 HTML 文件中,我在 table 中有以下 table 行,其中 {{ }} 只是变量:
<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
但我想让它保持异步。
任何帮助将不胜感激。
这可能是涉及 Javascript 闭包的问题吗?如果您在 for 循环内定义一个函数并在函数内分配变量,它们将通过成功回调保留其范围。
另一种(cleaner/more 优雅)解决方案会将 for
循环和函数调用重写为 Array.prototype.forEach() (thanks
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);
}
});
});