Javascript for循环中的ajax函数即使使用setTimeout也不更新DOM
我正在编写一个函数,在加载页面时使用ajax从后端服务器获取指令。我的ajax代码根据数字获取指令,并使用jquery和控制台在此元素中使用变量response.setText打印指令。以下是我的ajax函数:Javascript for循环中的ajax函数即使使用setTimeout也不更新DOM,javascript,jquery,html,ajax,dom,Javascript,Jquery,Html,Ajax,Dom,我正在编写一个函数,在加载页面时使用ajax从后端服务器获取指令。我的ajax代码根据数字获取指令,并使用jquery和控制台在此元素中使用变量response.setText打印指令。以下是我的ajax函数: function ajaxFetch(s) { var success = false; $.ajax({ type: "POST", url: "post.php", data: { step: s
function ajaxFetch(s) {
var success = false;
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
success = true;
}
});
return success;
}
function uploadSteps(maxStep) {
// here change `var x` to `let x` to avoid problems
// like here - https://stackoverflow.com/q/750486/5811984
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
// notice how here ajaxFetch(x) is wrapped into a function,
// otherwise it gets called right away
ajaxFetch(x)
}, 20);
}
}
我尝试使用另一个函数来循环执行步骤,无论有多少步骤,但我一直遇到以下问题:
ajaxFetch直到最后一次执行才更新DOM
已尝试设置超时,但未更新DOM
通过ajaxFetch的for循环过快
response.stepText会按时在控制台中打印,但不会按时更新DOM
以下是我尝试过的一个循环示例:
function uploadSteps(maxStep) {
for (var x = 1; x <= maxStep; x++){
setTimeout(ajaxFetch(x), 20);
}
}
抱歉,时间太长,请提前感谢。首先,我们需要修复uploadSteps功能中的错误:
function ajaxFetch(s) {
var success = false;
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
success = true;
}
});
return success;
}
function uploadSteps(maxStep) {
// here change `var x` to `let x` to avoid problems
// like here - https://stackoverflow.com/q/750486/5811984
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
// notice how here ajaxFetch(x) is wrapped into a function,
// otherwise it gets called right away
ajaxFetch(x)
}, 20);
}
}
因此,正如您所看到的,所有ajaxFetch都是同时调用的,我假设这并不是您所需要的。您可能正在寻找的是:
时间过去了,发生了什么
-------------
0ms |调用setTimeoutajaxFetch1、20
0ms | setTimeoutajaxFetch2,调用40
0ms | setTimeoutajaxFetch3,调用60
称为20ms | ajaxFetch1
称为40ms | ajaxFetch2
60毫秒| ajaxFetch3被称为
只需对代码稍加修改即可实现
函数上载StepSmaxStep{
对于设x=1;x20*x
}
}
另外,看起来您不需要从ajaxFetch返回任何内容,因此最好将其设置为异步,这样它就不会阻止代码执行:
函数ajaxFetchs{
$.ajax{
类型:POST,,
url:post.php,
数据:{
步骤:s
},
//async:false,-删除此项,默认情况下为true
数据类型:“JSON”,
成功:功能反应{
$loadText.textresponse.stepText;
console.logresponse.stepText;
}
};
}
即使您确实需要为fetchAjax返回一些内容,最好保持异步并使用回调/承诺。实际上强烈反对在任何情况下使用async:false
如果您添加设置超时的原因是为了确保所有步骤都按顺序执行,那么这不是正确的方法。问题是:
假设服务器响应第一个请求需要100毫秒,响应第二个请求需要10毫秒。即使有20毫秒的延迟,第二个请求也将首先执行。仅仅增加延迟并不是解决方案,因为:
如果您的服务器响应速度比延迟快得多,那么您将引入对用户不必要的等待。
最好添加一个来自ajaxFetch的回调,该回调将在ajax抓取完成时调用,然后在收到回调后调用下一个ajaxFetch。首先,我们需要修复uploadSteps函数中的错误:
function ajaxFetch(s) {
var success = false;
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
success = true;
}
});
return success;
}
function uploadSteps(maxStep) {
// here change `var x` to `let x` to avoid problems
// like here - https://stackoverflow.com/q/750486/5811984
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
// notice how here ajaxFetch(x) is wrapped into a function,
// otherwise it gets called right away
ajaxFetch(x)
}, 20);
}
}
因此,正如您所看到的,所有ajaxFetch都是同时调用的,我假设这并不是您所需要的。您可能正在寻找的是:
时间过去了,发生了什么
-------------
0ms |调用setTimeoutajaxFetch1、20
0ms | setTimeoutajaxFetch2,调用40
0ms | setTimeoutajaxFetch3,调用60
称为20ms | ajaxFetch1
称为40ms | ajaxFetch2
60毫秒| ajaxFetch3被称为
只需对代码稍加修改即可实现
函数上载StepSmaxStep{
对于设x=1;x20*x
}
}
另外,看起来您不需要从ajaxFetch返回任何内容,因此最好将其设置为异步,这样它就不会阻止代码执行:
函数ajaxFetchs{
$.ajax{
类型:POST,,
url:post.php,
数据:{
步骤:s
},
//async:false,-删除此项,默认情况下为true
数据类型:“JSON”,
成功:功能反应{
$loadText.textresponse.stepText;
console.logresponse.stepText;
}
};
}
即使您确实需要为fetchAjax返回一些内容,最好保持异步并使用回调/承诺。实际上强烈反对在任何情况下使用async:false
如果您添加设置超时的原因是为了确保所有步骤都按顺序执行,那么这不是正确的方法。问题是:
假设服务器响应第一个请求需要100毫秒,响应第二个请求需要10毫秒。即使有20毫秒的延迟,第二个请求也将首先执行。仅仅增加延迟并不是解决方案,因为:
如果您的服务器响应速度比延迟快得多,那么您将引入对用户不必要的等待。
最好添加一个来自ajaxFetch的回调,该回调将在ajax抓取完成时调用,然后在收到回调后调用下一个ajaxFetch。当for循环完成时,比如说20次迭代,ajaxFetch中的ajax调用只会收到前几个调用的响应 最后您看到的是对最后一个ajax调用的响应。您可以使用此链接了解异步调用在javascript中的工作方式 所以答案是,您需要等待第一个ajax调用完成,然后再次调用该方法,超时时间为20ms,如下所示
var globalMaxSteps = 1;
var startIndex = 1;
function ajaxFetch(s) {
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
startIndex++;
if(startIndex <= globalMaxSteps) {
setTimeout(function(){
ajaxFetch((startIndex);
},20);
} else {
console.log("All Iterations complete");
}
}
});
}
function uploadSteps(maxStep) {
startIndex = 1;
globalMaxSteps = maxStep;
setTimeout(function(){
ajaxFetch(startIndex);
},20);
}
当for循环完成时,比如说20次迭代,ajaxFetch中的ajax调用只会收到前几个调用的响应,最后看到的是最后一个ajax调用的响应。您可以使用此链接了解异步调用在javascript中的工作方式 所以答案是,您需要等待第一个ajax调用完成,然后再次调用该方法,超时时间为20ms,如下所示
var globalMaxSteps = 1;
var startIndex = 1;
function ajaxFetch(s) {
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
async: false,
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
startIndex++;
if(startIndex <= globalMaxSteps) {
setTimeout(function(){
ajaxFetch((startIndex);
},20);
} else {
console.log("All Iterations complete");
}
}
});
}
function uploadSteps(maxStep) {
startIndex = 1;
globalMaxSteps = maxStep;
setTimeout(function(){
ajaxFetch(startIndex);
},20);
}
我认为这是因为你使用了同步调用我认为这是因为你使用了同步调用setTimeout调用是错误的顺便说一句,你调用函数而不是将其作为参数传递。setTimeout调用是错误的顺便说一句,你调用函数而不是将其作为参数传递。