是否可以暂停while循环直到动画结束

Is it possible to pause a while loop until an animation finishes?

本文关键字:动画 结束 循环 while 暂停 是否      更新时间:2023-09-26

我正在尝试运行一个包含动画的while循环。我希望while循环暂停,让动画结束,然后继续。

这不是我实际的代码,但我相信它涉及到了问题:

var counter = 0;
while (counter < 2) {
    $(".one").animate({"left":"+=50px"}, "slow", function() {
        counter++;
    });
};

这会使我的浏览器崩溃,因为它不会等待动画完成(因此也不会等待计数器增加),然后再继续执行while循环。提前感谢!

https://jsfiddle.net/uhmctey6/

编辑

感谢大家解释为什么这是不可能的。然而,我仍然不确定如何做我需要的事情,由于我没有使用实际的代码作为示例,我不确定建议的解决方案是否有帮助。

这是我真正想做的:我正在制作一台图灵机器,它有一个阅读器和一组可以读取的细胞。在运行这个函数时,我想搜索图灵代码行的列表,看看其中一行是否与阅读器的当前状态和阅读器正在扫描的当前单元格的内容相匹配。如果有匹配,我希望读者做出相关图灵代码行指定的一系列更改,然后视觉上移动到下一个单元格,只有在这个动画完成之后,通过搜索图灵代码列列表来重新开始该过程,看看是否有与读者的新状态匹配的内容,等等。

我知道使用while循环无法实现这一点,但有没有其他方法可以做到这一点?非常感谢!

var run_program = function() {
    while (true) {
        for (var j=0; j< program.length; j++) {    //loops through the different lines of turingcode
            if (reader.state === program[j].state && reader.scanning === program[j].scanning) { //if there is a line of turingcode for the readers current state and scanning values.
                cellArray[reader.location].content = program[j].print; //change the content of the current cell to the new value
                reader.location += 1; //increase the value of the reader's location
                $(".reader").animate({"left":"+=50px"}, "slow"); //move the div to the right so it appears to be under the next cell
                reader.scanning = cellArray[reader.location].content; //update the readers scanning value to be the value of the new cell
                reader.state = program[j].next_state; // update the state of the reader to that specified by the line of turingcode
                break;
            }
            else if (j === $scope.program.length-1) { //if there is no line of turingcode for the readers current state and scanning values, and j has looped through the entire list of turingcode lines
                return;  //halt the function
            }
        }
    }
}

for循环/while循环可以运行、跳过和跳跃,但不能静止。

换句话说,您不能在同步循环中有效地运行异步代码。请参阅此问题/答案以了解更多信息。

同时,看起来你想按顺序运行一个动画几次。我相信jQuery可以像animate一样对效果进行排队,所以它可以像链接两个调用来动画一样简单:

$(".one")
      .animate({"left":"+=50px"}, "slow")
      .animate({"left":"+=50px"}, "slow"); /* animate twice */
.one {
  
  position: absolute;
  width: 50px;
  height: 50px;
  
  background-color: green;
  
  left: 0;
  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="one"></div>

更新

作为对您的编辑的回应,您似乎想做的是将一段高度同步的代码转换为一段可以适应一些偶尔异步行为的代码。

不幸的是,你的例子对我来说是不可行的,因为它没有数据和上下文。然而,我已经捅了它一刀。以下是未经测试的,我将如何将您的代码转换为您在问题编辑中描述的内容。我希望它能有所帮助。

var run_program = function() {
  next(0);
  // read a particular iteration
  function next (j) {
    if (j < program.length) {
      // if there is a match, stop iterating and run a method which calls next when it's finished
      if (reader.state === program[j].state && reader.scanning === program[j].scanning) {
        turing(j);
      } else {
        // if there is no turing code then next is called instantly
        next(j + 1);
      }
    }
  }
  // process a line of turing code
  function turing (j) {
    cellArray[reader.location].content = program[j].print;
    reader.location += 1;
    reader.scanning = cellArray[reader.location].content;
    reader.state = program[j].next_state;
    // may as well run this last as it is asynchronous
    $(".reader").animate({"left":"+=50px"}, "slow", function () {
      // next is called when the animation is finished
      next(j + 1);
    });
  }
}

由于其他答案中所述的原因,这将不起作用。另一种选择是使用条件递归:

var counter = 0;
function myAnimation () {
  $(".one").animate({"left":"+=50px"}, "slow", function () {
    counter++;
    if (counter < 2) {
      myAnimation();
    }
  });
}