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

时间:2015-11-27 19:32:27

标签: javascript jquery

我试图运行包含动画的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

            }

        }

    }

}

2 个答案:

答案 0 :(得分:3)

for循环/ while循环可以运行,跳过和跳转 - 但不能停滞不前。

换句话说,您无法在同步循环中有效地运行异步代码。有关详情,请参阅this问题/答案。

与此同时,您希望按顺序运行动画几次。我相信jQuery可以对像animate这样的效果进行排队,所以它可以像将两个调用链接到动画一样简单:

&#13;
&#13;
$(".one")
      .animate({"left":"+=50px"}, "slow")
      .animate({"left":"+=50px"}, "slow"); /* animate twice */
&#13;
.one {
  
  position: absolute;

  width: 50px;
  height: 50px;
  
  background-color: green;
  
  left: 0;
  
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="one"></div>
&#13;
&#13;
&#13;

<强> 更新

为了响应您的编辑,您似乎想要做的是将一段高度同步的代码转换为可以容纳一些偶尔异步行为的代码。

不幸的是,您的示例对我来说是行不通的,因为它没有数据和上下文。但是,我给了它一个刺。以下是未经测试的,我将如何将您的代码转换为您在编辑问题时所描述的内容。我希望它有所帮助。

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);

    });
  }
}

答案 1 :(得分:1)

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

var counter = 0;

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