让 for 循环等待代码完成执行 javascript

Let for loop wait until code finish execution javascript

本文关键字:执行 javascript 代码 for 循环 等待      更新时间:2023-09-26

我有一个气泡排序函数,当交换发生时,它应该明显显示它。但是经过许多方法后,它会继续执行循环,而无需等待动画停止。(我们只允许使用 JavaScript)。有没有办法告诉网站等待动画完成。这是我的代码片段:

for (var i = 0; i < len; i++) 
{
    for (var j = 0, swapping, endIndex = len - i; j < endIndex; j++) 
    {
        if (marksArr[j] > marksArr[j + 1]) 
        {
            //swap objects


            /*(function() {
                var k = 0,
                    action = function() {
                        document.getElementById(coursesKey[j]).style.top = (parseInt(document.getElementById(coursesKey[j]).style.top) + 1) + 'px';
                        document.getElementById(coursesKey[j + 1]).style.top = (parseInt(document.getElementById(coursesKey[j+1]).style.top) - 1) + 'px'; 
                        k++;
                        if (k < difMoves) {
                            setTimeout(action, 200);
                        }
                    };
                setTimeout(action, 200);
            })();*/

        }
    }
}

正如@cookie怪物已经解释的那样,你不能在 JavaScript 中阻塞循环并同时使用 setTimeout() 更新 UI(这是因为 JavaScript 本质上是单线程的)。

最优雅的解决方案是在for循环处理数组时"记录"每个动画步骤,然后运行动画,例如使用 setTimeout() 。前段时间,我已经在 StackOverflow 上为一个类似的问题实现了这种方法;这是一个演示:JSFiddle

代码也可以简化:

function swap(list, i1, i2) {
    var tmp = list[i1];
    list[i1] = list[i2];
    list[i2] = tmp;
}
function animateBubblesort(list) {
    var animationSteps = [];
    // Sort array
    for (var n = list.length; n > 1; --n) {
        for (var i = 0; i < n-1; ++i) {
            if (list[i] > list[i+1]) {
                swap(list, i, i+1);
                // Add new step (clone of current array) to "animation queue"
                animationSteps.push(list.slice(0));
            }
        }
    }
    // Print animated steps (using setInterval() for simplicity)
    var count = 0, 
        interval = setInterval(function(){
            console.log(animationSteps[count]);
            if (++count >= animationSteps.length) {
                clearInterval(interval);
            }
        }, 250);
}
animateBubblesort([5,8,2,4,1,9,7,3,0,6]);

演示

另一种(不太直观)的可能性是实现没有循环的算法,以便控制算法的下一步何时执行(这样你就有时间制作动画)。下面是一个示例:演示 2