【问题标题】:Is it possible to pause a while loop until an animation finishes?是否可以暂停while循环直到动画完成?
【发布时间】:2015-11-29 01:35:42
【问题描述】:

我正在尝试运行一个包含动画的 while 循环。我想要发生的是让while循环暂停,让动画完成,然后继续。

这不是我的实际代码,但我相信它解决了问题:

var counter = 0;

while (counter < 2) {

    $(".one").animate({"left":"+=50px"}, "slow", function() {

        counter++;

    });
};

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

https://jsfiddle.net/uhmctey6/

编辑

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

这就是我真正想做的事情:我正在制作一个带有阅读器和它读取的单元阵列的图灵机。运行此功能后,我想搜索图灵代码行列表,以查看其中是否与阅读器当前状态和阅读器正在扫描的当前单元格的内容相匹配。如果匹配,我希望读者根据相关的图灵代码行进行一系列更改,然后在视觉上移动到下一个单元格,并且只有在此动画完成后 em> 重新开始这个过程,通过搜索图灵代码行列表来查看是否有匹配阅读器的新状态等。

我知道这不能像我拥有的​​那样使用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

            }

        }

    }

}

【问题讨论】:

  • 您到底想做什么?您是否尝试在每个动画步骤中更新计数器值?还是要多次运行同一个动画?
  • 不,不是。 JavaScript 的评估绑定到单个线程。 while 循环将无限期地保持线程忙碌,防止执行任何其他事件,包括 .animate() 回调。
  • 这不是我的实际代码,它只是一个简化的例子。但我想在这个例子中,我希望动画运行两次,每次动画完成后增加计数器。

标签: javascript jquery


【解决方案1】:

for 循环/while 循环可以运行、跳过和跳转 - 但不能静止不动。

换句话说,您不能在同步循环中有效地运行异步代码。有关更多信息,请参阅this question/answer。

与此同时,您似乎想按顺序运行几次动画。我相信 jQuery 可以像animate 这样对效果进行排队,所以它可以像将两个调用链接到 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);

    });
  }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      相关资源
      最近更新 更多