【问题标题】:Create a pause inside a while loop in Javascript在 Javascript 中的 while 循环内创建暂停
【发布时间】:2011-05-31 16:29:41
【问题描述】:

我想在 while 循环中创建一个暂停,以便我可以创建 n 动画,每个动画在另一个之后出现 3 秒。

我尝试了以下方法,但它不起作用。希望有人告诉我我做错了什么。

i=0;
while (i < n) {
    someanimation();
    setTimeout(function(){
        i++;
    }, 3000);
     
};

【问题讨论】:

标签: javascript while-loop dom-events


【解决方案1】:

setTimeout 不会暂停;它要求 Javascript 稍后运行其他代码。

搜索“setTimeout 循环”可以准确告诉您需要了解的内容。如果你环顾四周,它甚至会提到 setInterval。区别:使用 setTimeout 循环将在循环之间等待 3 秒,而 setInterval 将使循环总共需要 3 秒(包括动画花费的时间,只要它少于 3 秒 :) )。此外, setInterval 构造了一个无限循环,您必须在所需的次数后退出该循环; setTimeout 需要你自己构建循环。

i = 0;

// setTimeout approach
function animation_loop() {
  someAnimation();
  setTimeout(function() {
    i++;
    if (i < n) {
      animation_loop();
    }
  }, 3000);
};
animation_loop();

// setInterval approach
i = 0;
someAnimation();
iid = setInterval(function() {
  i++;
  if (i < n) {
    someAnimation();
  } else {
    clearInterval(iid);
  }
}, 3000);

【讨论】:

  • 你摇滚!!非常感谢 - 我是一个真正的初学者,所以我不熟悉这些成语,而且我并不总是知道谷歌的最佳关键字是什么。不管怎样,你真的让我大开眼界了!!
  • 这个答案引入了一个无限的setInterval。我最好在i &gt;= n时清除setInterval
  • @A1rPun 同意;我更新了代码以包含它(以及更清晰地标记正在发生的事情)。
【解决方案2】:

好吧,感谢带有 Promises 的 ES6-7,我们现在可以暂停一下,同时让它看起来更漂亮!

var id = 0;

async function do() {
  while(true) {
    await pause(id);
    //will happen only after pause is done
    id++; 
  }
}
function pause(id) {
  return new Promise(resolve => setTimeout(() => {
    console.log(`pause ${id} is over`);
    resolve();
  }, 1500)); 
}

do();

【讨论】:

    【解决方案3】:

    其中一种方法是使用 RxJS。请看working example here

    Rx.Observable
      .interval(1000)
      .take(10)
      .subscribe((x) => console.log(x))
    

    【讨论】:

      【解决方案4】:
      function myFunction() {
          var x;
      for(var i=0;i<10;i++){
          if (confirm("Press a button!") == true) {
              x = "You pressed OK!";
          } else {
              x = "You pressed Cancel!";
          }
          document.getElementById("demo").innerHTML = x;
      }
      }``
      

      【讨论】:

        【解决方案5】:

        setTimeout 比这要复杂一些,因为它不会阻塞(即在继续程序之前它没有完成等待超时)。

        你想要的更接近这个:

        var i = 0;
        function nextFrame() {
            if(i < n) {
                someanimation();
                i++;
                // Continue the loop in 3s
                setTimeout(nextFrame, 3000);
            }
        }
        // Start the loop
        setTimeout(nextFrame, 0);
        

        也许值得您阅读setInterval 作为一种可能的替代方案。

        【讨论】:

          【解决方案6】:

          创建一个类似的函数:

          function sleep_until (seconds) {
             var max_sec = new Date().getTime();
             while (new Date() < max_sec + seconds * 1000) {}
              return true;
          }
          

          然后将代码更改为

          i=0;
          while (i < n) {
              someanimation();
              sleep_until(3);
              do_someotheranimation();
          };
          

          【讨论】:

          • 阻止 js 正是我想要的。
          • 有时您确实想阻止引擎..(希望只是为了测试)
          【解决方案7】:

          您对自己想要做什么并不是很具体,但我想说主要问题是您毫不拖延地致电someanimation()。所以也许这可以为你解决:

          for (var i = 0; i < n; i++) {
              setTimeout(someanimation, 3000 * i);
          };
          

          注意someanimation 后面缺少的(),因为它是setTimeout() 的回调。

          【讨论】:

          • 请不要重新发明有标准成语的东西。
          • @Karl Knechtel:你在说什么?什么“标准习语”?你的想法是一样的。唯一的区别是您在计时器函数中启动了对someanimation() 的下一次调用。
          • "...您在计时器函数中启动对 someanimation() 的下一次调用。"这正是标准的成语。这样,一次只有一个回调入队。
          • 这将同时将所有迭代排入队列,然后等待 3 秒以同时转储对某个动画的调用。
          • @BrettMathe *sigh* jsfiddle.net/fw4mmgca 看看时间戳。请在下次投反对票之前弄清楚你的事实。
          猜你喜欢
          • 1970-01-01
          • 2017-03-12
          • 2019-08-31
          • 2021-03-04
          • 2017-10-25
          • 1970-01-01
          • 2014-04-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多