Javascript 对于连续多次setTimeout调用未正确重复的循环?
长话短说,我在chrome开发者控制台中工作,我有一个javascript函数(我决定调用main进行说明),它可以进行4个函数调用,但4个函数调用中的每一个都需要间隔几秒钟,以允许页面正确更新,并允许用户对生成的对话框做出反应 当我在内部的4个函数调用中添加一个带有延迟的setTimeout并运行一次时,main函数工作得非常好。当我尝试将主函数循环X次时,它不起作用 通过阅读其他类似问题和文档,我可以了解到,这与setTimeout如何工作以及chrome浏览器中的javascript引擎如何是单线程的复杂性有关。。。还是什么?虽然不是我的专业知识,但我尝试过尽职调查,最终我不知道如何解决问题,甚至搜索其他问答和文档也无法找到有效的解决方案 我用setTimeout(,delay*I)方法和setTimeout(,delay)方法尝试了下面的代码,但是没有传入for循环的索引来乘以延迟,这两种方法都不能正常工作 其他问题建议使用嵌套设置超时,我不知道如何在这里实现?还有人建议使用setInterval,但我不确定如何在一定的时间内完成这一任务,因为我的每个调查都有一定数量的问题,我不希望主函数的重复次数超过调查中的最大问题量Javascript 对于连续多次setTimeout调用未正确重复的循环?,javascript,jquery,Javascript,Jquery,长话短说,我在chrome开发者控制台中工作,我有一个javascript函数(我决定调用main进行说明),它可以进行4个函数调用,但4个函数调用中的每一个都需要间隔几秒钟,以允许页面正确更新,并允许用户对生成的对话框做出反应 当我在内部的4个函数调用中添加一个带有延迟的setTimeout并运行一次时,main函数工作得非常好。当我尝试将主函数循环X次时,它不起作用 通过阅读其他类似问题和文档,我可以了解到,这与setTimeout如何工作以及chrome浏览器中的javascript引擎如
for(let i = 1; i < 15+1; i++) {
main(i);
}
function main(i){
setTimeout(takescreenshot, 2000*i);
setTimeout(checkforanswers,5000*i);
setTimeout(takescreenshot, 8000*i);
setTimeout(function(){$("[name=next_question_button]")[0].click();},11000*i);
}
for(设i=1;i<15+1;i++){
主要(i);
}
主要功能(一){
设置超时(截图,2000*i);
设置超时(检查应答,5000*i);
设置超时(截图,8000*i);
setTimeout(函数(){$(“[name=next_question_button]”[0])。单击();},11000*i);
}
主函数应该每次循环任意次数,在我看来,程序流程应该是:
当执行一次时,它完全按照我所希望的那样工作,但是当循环多次时,步骤1-4开始出现,没有适当的延迟,并且在每个步骤中的相关“等待X”得到满足之前开始出现,并且所有这些都混合在一起,获得不可预测和不想要的结果。您的算法已关闭。您应该将
i
乘以完成整个迭代所需的时间,然后再加上2、5或8秒。例如,如果从一次迭代的takescreenshot
到下一次迭代的takescreenshot
所需时间为14000 ms,则使用:
function main(i){
setTimeout(takescreenshot, 2000 + (i * 14000));
setTimeout(checkforanswers,5000 + (i * 14000));
setTimeout(takescreenshot, 8000 + (i * 14000));
setTimeout(function(){$("[name=next_question_button]")[0].click();},11000 + (i * 14000));
}
如果您指定函数并在for
循环中等待中的每个调用,则操作顺序会更清晰:
(async () => {
for (let i = 1; i < 15 + 1; i++) {
await main();
}
})();
function main() {
setTimeout(takescreenshot, 2000);
setTimeout(checkforanswers, 5000);
setTimeout(takescreenshot, 8000);
return new Promise((resolve) => {
setTimeout(function() {
$("[name=next_question_button]")[0].click();
resolve();
}, 11000);
});
}
(异步()=>{
for(设i=1;i<15+1;i++){
等待main();
}
})();
函数main(){
设置超时(截图,2000年);
设置超时(检查应答,5000);
设置超时(截图,8000);
返回新承诺((解决)=>{
setTimeout(函数(){
$(“[name=next\u question\u button]”[0]。单击();
解决();
}, 11000);
});
}
如果i
为2
则设置超时(截图,2000*i)调用main后的2000*2
毫秒将被调用
但您希望它在调用main后的几毫秒内被调用11000+2000
。其他超时情况也是如此
由于i
以1
开头,您希望使用11000*(i-1)
作为添加到每个超时函数的延迟
function main(i){
let delay = 11000 * (i - 1);
setTimeout(takescreenshot, 2000 + delay );
setTimeout(checkforanswers, 5000 + delay );
setTimeout(takescreenshot, 8000 + delay );
setTimeout(function(){$("[name=next_question_button]")[0].click();}, 11000 + delay);
}
以下是经典的分块方法:
function chunks([first, ...other], delay = 2000, result) {
const nextResult = first(result);
setTimeout(() => chunks(other, delay, nextResult), delay);
}
const simpleFunction = () => { return 'whatever'; };
const functionWithParams = (a, b) => a + b;
const pipe = [
simpleFunction,
() => functionWithParams(3, 5),
data => console.log('inline code to run, which uses prev result (3+5=8): ' + data),
];
chunks(pipe);
// or chunks(pipe, 5000);
for循环不等待,因此您只需对整个循环进行间隔毫秒的超时调用。因此,您基本上要调用takescreenshot
15次。
只需使用main调用自己。在最后一次超时中,调用main以重复
function main(i){
setTimeout(takescreenshot, 2000*i);
setTimeout(checkforanswers,5000*i);
setTimeout(takescreenshot, 8000*i);
setTimeout(function(){
$("[name=next_question_button]")[0].click();}
if (i<14) {
main(i+1)
}
}, 11000*i)
}
main(0)
主功能(一){
设置超时(截图,2000*i);
设置超时(检查应答,5000*i);
设置超时(截图,8000*i);
setTimeout(函数(){
$(“[name=next_question_button]”[0]。单击();}
如果我的解决方案和上面提到的“t.niese”解决方案都能解决我的问题。实际上,我认为我正在实现一个类似于上面提出的“等待”解决方案的解决方案,在解决所有问题之前,主循环不会开始下一次迭代,但我最初实现了一个类似于“t.niese”的解决方案但我的算法不正确。感谢你们和其他评论者!