如何在Javascript中使用延迟和标志条件(类似事件处理程序)执行函数?

如何在Javascript中使用延迟和标志条件(类似事件处理程序)执行函数?,javascript,Javascript,我正在用Javascript编写一个程序,它接受输入字符串,然后对每个字符串进行模拟。用户决定速度,即处理每个字符串之间的延迟。我使用setInterval()函数来控制它。但是,我遇到了一个问题,较长的字符串可能无法处理,因为最后一个字符串仍在处理中。这导致我犯了一系列错误。这里有一些代码来描绘更好的画面 let testingInterval = setInterval(function () { strprn.innerHTML = `<h2>${strings[i

我正在用Javascript编写一个程序,它接受输入字符串,然后对每个字符串进行模拟。用户决定速度,即处理每个字符串之间的延迟。我使用setInterval()函数来控制它。但是,我遇到了一个问题,较长的字符串可能无法处理,因为最后一个字符串仍在处理中。这导致我犯了一系列错误。这里有一些代码来描绘更好的画面

let testingInterval = setInterval(function () {
      strprn.innerHTML = `<h2>${strings[i]}<\h2>`; // displays current string to user
      if (i + 1 == strings.length) { // checks if should notify user all strings have been processed
        checker.finalCheck = true;//the checker uses this flag to notify the user once the test completes
      }
      checker.check(strings[i]); //runs the check i.e. simulation
      i++; // increments the counter iterating through the array (setup code not shown here)
      if (i >= strings.length) { 
        clearInterval(testingInterval); //once we reach the end stop the interval iterating
        evenOutResults(); // clean up answers function
        updateTimeStamp(Date.now()); // for readability, I add a timestamp of when the results were generated
      }
    }, delay); // user specified delay
let testingInterval=setInterval(函数(){
strpn.innerHTML=`${strings[i]}`;//向用户显示当前字符串
if(i+1==strings.length){//检查是否应该通知用户所有字符串都已处理
checker.finalCheck=true;//检查程序使用此标志在测试完成后通知用户
}
checker.check(strings[i]);//运行检查,即模拟
i++;//递增遍历数组的计数器(此处未显示设置代码)
如果(i>=strings.length){
clearInterval(testingInterval);//一旦到达终点,停止区间迭代
evenOutResults();//清除答案函数
updateTimeStamp(Date.now());//为了可读性,我添加了生成结果的时间戳
}
},延迟);//用户指定延迟
我要寻找的是一种方式,以尊重延迟,但也不开始下一个调用,直到当前字符串已完成处理

逻辑上是这样的(下面的代码冻结了浏览器XD):

函数delayLoop(){
setTimeout(函数(){
strpn.innerHTML=`${strings[i]}`;
if(i+1==strings.length){
checker.finalCheck=true;
}
checker.check(字符串[i]);
i++;
if(i
如果我错了,请纠正我的错误,但看起来好像你想要一个你想要“消息”的约会时间表如果在约会时未准备好消息,则您希望它重新安排到下一个约会。通过某种迭代,您可以轻松找到下一个可用的约会

const nextCheckin=(上次签入,间隔)=>{
while(lastCheckin
假设消息的顺序很重要,您可以这样做

const simulation = (strings, delay) => {
  let checkin = Date.now() + delay
  for (const str of strings) {
    const result = simulate(str)
    checkin = nextCheckin(checkin, delay)
    console.log(`Waiting for: ${checkin-Date.now()}`)
    while (Date.now() < checkin)
      continue
    reportWork(result)
  }
}
const模拟=(字符串,延迟)=>{
让checkin=Date.now()+延迟
for(字符串的常量str){
常量结果=模拟(str)
签入=下一次签入(签入,延迟)
log(`Waiting:${checkin Date.now()}`)
while(Date.now()<签入)
持续
报告工作(结果)
}
}

while循环将导致事件循环挂起,因此调用
setTimeout
可能更合适,但无论什么都会使船浮起。

对不起,我应该对此进行更多说明。Checker.check()是一个使用setInterval()的函数显示动画。需要对一组对象执行动画。由于setInterval(),任何时候我们等待都意味着javascript将尝试执行下一行代码。这意味着香草for循环是不可能的

我最初的解决方案是将for循环迭代本身放入setTimeout()中。只要延迟足够长,所有被迭代的对象都可以使用。问题是对象很少,所以如果一个对象比之前的对象大,并且延迟很短,那么整个动画就会崩溃。最后,Promises是最简单的解决方案

     let runLoop = async () => {
        for(var i = 0; i < strings.length; i++){
          strprn.innerHTML = `<h2>${strings[i]}<\h2>`;
          console.log("about to await");
          if (i + 1 == strings.length){
            checker.finalCheck = true;
          }
          await new Promise(resolve => checker.check(resolve, strings[i]));
          if (checker.finalCheck){
            updateTimeStamp(Date.now());
          }
        }
      }
      runLoop();
let runLoop=async()=>{
for(var i=0;ichecker.check(resolve,strings[i]);
if(checker.finalCheck){
updateTimeStamp(Date.now());
}
}
}
runLoop();
对于那些对此感到疑惑并寻找答案的人,wait会暂停执行,直到满足解析。您将解析传递给函数,并在setInterval()代码块的最后调用resolve()。为了使用wait,整个过程都被封装在一个异步函数中

     let runLoop = async () => {
        for(var i = 0; i < strings.length; i++){
          strprn.innerHTML = `<h2>${strings[i]}<\h2>`;
          console.log("about to await");
          if (i + 1 == strings.length){
            checker.finalCheck = true;
          }
          await new Promise(resolve => checker.check(resolve, strings[i]));
          if (checker.finalCheck){
            updateTimeStamp(Date.now());
          }
        }
      }
      runLoop();