【问题标题】:How to break a for-loop with a nested setTimeout() function in javascript?如何在javascript中使用嵌套的setTimeout()函数打破for循环?
【发布时间】:2019-05-22 03:35:23
【问题描述】:

情况

我有一个在按钮单击时调用的函数,它应该绘制一个动画图表,每 2 秒更新一次图表。当用户再次单击该按钮时,动画仍在运行,动画应该停止。

我目前的解决方案

现在我有以下脚本可以在视觉上停止动画,但底层的 for 循环会一直持续到后台结束:

var animRun = false;
$("#animateButton").on("click", function() {
    if (animRun === false) {
        redraw(data.slice(0,30))
        //some CSS...

    } else {
        //Some CSS...
        animRun = false;
    }
});

function redraw(data) {
    animRun = true;

    for (var i=0; i<data.length;i++){

        (function(i){
            setTimeout(function(){
                if(animRun === true) {
                    //draw the chart
                    return draw(data[i])
                }
            },2000*(i))

            if (i === data.length -1) {
                //reset animRun
                if(animRun === true) {
                     //Some CSS things
                     //...
                     animRun = false;
                 }
            }
        })(i);
    }


}

问题

当用户在动画仍在执行时再次单击按钮时,停止 for 循环的正确方法是什么?

【问题讨论】:

标签: javascript for-loop settimeout


【解决方案1】:

你试过clearTimeout。将绘制超时存储到一个数组中,并在完成后停止它

var animRun = false;
var drawArr = [];
$("#animateButton").on("click", function() {
    if (animRun === false) {
        redraw(data.slice(0,30))
        //some CSS...

    } else {
        //Some CSS...
        animRun = false;

        drawArr.forEach(d=>clearTimeout(d));
    }
});

function redraw(data) {
    animRun = true;

    for (var i=0; i<data.length;i++){

        (function(i){
            drawArr[i] = setTimeout(function(){
                if(animRun === true) {
                    //draw the chart
                    return draw(data[i])
                }
            },2000*(i))

            if (i === data.length -1) {
                //reset animRun
                if(animRun === true) {
                     //Some CSS things
                     //...
                     animRun = false;
                 }
            }
        })(i);
    }


}

【讨论】:

  • 谢谢!这就像一个魅力!我只是不明白为什么它应该是一个列表。因为列表在每次迭代后都会填满,不是吗?因此,如果用户在第一次运行draw() 后停止动画,则drawArr 中只有一个元素。它是如何清除所有后续迭代的?
  • 当您再次单击开始时重新初始化该数组drawArr = []
猜你喜欢
  • 1970-01-01
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 2012-03-30
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
相关资源
最近更新 更多