Javascript 在循环中设置超时,在前一个函数完成后执行3个函数
I 3个函数a、b和c将在循环中执行x次,如下所示: 我必须调用函数a;a完成后,我必须等待s1秒才能调用函数b;s1秒过后,我必须调用函数b;b完成后,我必须等待2秒才能重新启动循环Javascript 在循环中设置超时,在前一个函数完成后执行3个函数,javascript,jquery,loops,settimeout,deferred,Javascript,Jquery,Loops,Settimeout,Deferred,I 3个函数a、b和c将在循环中执行x次,如下所示: 我必须调用函数a;a完成后,我必须等待s1秒才能调用函数b;s1秒过后,我必须调用函数b;b完成后,我必须等待2秒才能重新启动循环 for(var i=0; i<x; i++) { a(); setTimeout(b,s1); setTimeout(function() {},s2); } 然而,在上述循环中,函数a和b不能正确执行。无论上一个函数是否已完成,都会执行它们 我还尝试了: var FunctionOne = functi
for(var i=0; i<x; i++) {
a();
setTimeout(b,s1);
setTimeout(function() {},s2);
}
然而,在上述循环中,函数a和b不能正确执行。无论上一个函数是否已完成,都会执行它们
我还尝试了:
var FunctionOne = function () {
// create a deferred object
var r = $.Deferred();
// do whatever you want (e.g. ajax/animations other asyc tasks)
a();
setTimeout(function () {
// and call `resolve` on the deferred object, once you're done
r.resolve();
}, s1);
// return the deferred object
return r;
};
var FunctionTwo = function () {
b();
};
for(var i=0; i<x; i++) {
setTimeout(FunctionOne().done(FunctionTwo),s2);
}
但它并没有达到预期的效果
你能帮我吗
编辑
职能a和b如下:
function a() {
$.ajax({
type: $('#form1').attr('method'),
url: 'Misura',
data: $('#form1').serialize(),
beforeSend: function() {
if($.trim($('#nomeMisura').val()) == "") {
alert('<%= labels.getString("nomeMisuraObbligatorio") %>');
$('#nomeMisura').val("");
return false;
}
},
success: function (data) {
$('#misura').attr('disabled', true);
$('#pulisci').attr('disabled', false);
misurazioneInCorso = true;
}
});
}
}
因此,我认为a和b是异步函数。您可以实现某种调度器:下面我使用一个最简单的堆栈,其中包含函数或下一个任务执行前的等待时间。 下面的代码未经测试,但可能会给您一些想法:
var tasks = []; // list of all tasks / wait time
var currTaskIndex = 0;
var looping = true;
function runTask() {
if (currTaskIndex==-1) return;
var currTask = tasks[currTaskIndex];
// iterate
currTaskIndex++;
if (currTaskIndex==tasks.length) {
if(looping ) {
currTaskIndex=0;
} else {
currTaskIndex=-1;
}
}
// run task / wait
if (typeof currTask == "function") {
currTask.call(null);
runTask();
} else {
// currTask is a time -> wait
setTimeout(runTask, currTask);
}
}
配合使用
tasks.push(a);
tasks.push(s1);
tasks.push(b);
tasks.push(s2);
runTask();
对于异步调用,始终需要将下一步(取决于异步活动的结果)放入异步活动结束时调用的回调方法中 根据您的评论,您的方法包含异步ajax调用。setTimeout调用也是异步的。如果你打电话:
setTimeout(b,s1);
setTimeout(c,s2);
然后两个超时将同时运行。这意味着你正在进入地狱的世界……这并不像有些人想象的那么难,但这是一种不同的思维方式
为了防止后续方法执行,并防止循环仅仅进入下一个迭代并同时执行整个循环,您需要在a的末尾调用b,在b的末尾调用c。在开始下一次迭代之前,您还必须等待c的结束,这意味着在c完成后循环,而不是将c放入循环中……否则,您的循环将立即通过所有x次迭代,并且您将让所有方法几乎同时运行,除了a,因为它是一个同步调用,考虑到我之前提到的假设。因此,您需要做的是:
var i = 0;
var x = 100;
function a() {
//end our loop inside the method
if( i++ < x ) {
//shortening your ajax call to just success method
var ajaxSuccess = function (data) {
$('#misura').attr('disabled', true);
$('#pulisci').attr('disabled', false);
misurazioneInCorso = true;
setTimeout(b,s1);
}
}
}
function b() {
//shortening your ajax call to just success method
var ajaxSuccess = function (data) {
var numeroCampioniMisurazione = Number(data.delta.campione2) - Number(data.delta.campione);
//visualizzo in tabella le misurazioni
$('#tabellaMisurazioni').append('<tr id="Misurazione"><td>'+data.nomeSessione+'</td><td>'+data.nome+'</td><td>'+data.delta.campione+'</td><td>'+data.delta.campione2+'</td><td>'+numeroCampioniMisurazione+'</td><td>'+data.delta.f1+'</td><td>'+data.delta.f2+'</td><td>'+data.delta.f3+'</td><td>'+data.delta.f4+'</td><td>'+data.delta.f5+'</td><td>'+data.delta.f6+'</td><td>'+data.delta.f7+'</td><td>'+data.delta.f8+'</td><td>'+data.delta.f9+'</td><td>'+data.delta.f10+'</td><td>'+data.delta.f11+'</td><td>'+data.delta.f12+'</td><td>'+data.delta.t1+'</td><td>'+data.delta.t2+'</td><td>'+data.delta.to+'</td><td>'+data.delta.ft+'</td><td>'+data.delta.rh+'</td></tr>');
$('#tabellaMisurazioni tbody tr:first').html('<td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td><td>---</td>');
$('#misura').attr('disabled', false);
$('#pulisci').attr('disabled', true);
$('#esportaCsvMisurazioni').attr('disabled', false);
$('#nomeMisura').val('');
misurazioneInCorso = false;
setTimeout(c,s2);
}
}
function c() {
//do your stuff, then loop back to a
a();
}
a();
注意,我正在做的唯一一件事是将下一个调用放入AJAX调用的success方法中,我通过使用c调用a而不是将其放入for循环来循环。然后,我修改了a,这样它将在x次迭代后结束循环,而不在if中执行。这将确保它们按顺序运行。我建议的代码与Kevin Nelson的代码非常相似。在我的代码中,控制逻辑不包括在应用程序函数中
var x=5;
outerFun(){
if(x){
a();
setimeout(function(){
b();
setTimeout(function(){
//do its part
x--;
outerFun();
},s2);
},s1);
}
}
您可以在以下链接中找到我的解决方案的PDF版本-其中包括分析,代码可能在末尾找到:
以下是从PDF文档生成的
在第二种方法中,有什么不起作用?是同步的还是异步的?我用a和b函数编辑了我的第一篇文章。它们似乎是异步函数$.ajax调用。我还没有时间尝试任何提议的解决方案。我不知道哪一个适合异步函数。已更新为使用来自ajax调用的回调。我不确定此解决方案是否能按我的要求工作,因为a和b函数包含异步ajax调用。例如,在函数PL1中,我需要a在调用setTimeoutPL2、s1之前完成其所有任务。我不知道为什么,但您的解决方案似乎有效:非常感谢!
var x=5;
outerFun(){
if(x){
a();
setimeout(function(){
b();
setTimeout(function(){
//do its part
x--;
outerFun();
},s2);
},s1);
}
}