首先,我查看了所有的“睡眠”问题(例如What is the JavaScript version of sleep()?),但没有找到可接受的解决方案。
我想为各种算法制作一个视觉教育工具。为了做到这一点,我使用带有 jQuery 的 javascript 来显示数据并很好地绘制它。为了启动它,我想做一个排序示例,其中显示一个数组,打乱然后以视觉上令人愉悦的方式排序。所以我想要发生的是两个单元格被突出显示(容易),可能交换(容易),然后在测试下一对(困难)之前有一个小的延迟。
我知道 javascript 中没有明确的“睡眠”方法。但是,将代码重构为使用 setTimeout 将意味着递归地重写我的所有算法,这是一个巨大的障碍(尽管显然并非不可能)。
作为一个示例问题,请看一个冒泡排序示例:
function bubble_sort(arr){
for(var i=0;i<arr.length;i++){
for(var j=1;j<arr.length;j++){
highlight(j-1);
highlight(j);
if(arr[j-1] > arr[j]){
visible_swap(arr, j, j-1);
}
sleep(1000);
}
}
exhibit_array(arr);
}
这显然可以递归地重写以使用 setTimeout,但是在我想到的所有算法上这样做会花费大量时间。我错过了什么吗?有没有一种“简单”的方法可以让实现保持原样并随意放置睡眠?
编辑:我找到了两个解决方案:一个漂亮的,一个兼容的。恐怕这个漂亮的只适用于 Firefox,并利用了美妙的产量语义(这里有一些示例解释:https ://developer.mozilla.org/en/New_in_JavaScript_1.7 )。这实际上完美地解决了我的问题,因此:
function bubble_sort(arr){
for(var i=0;i<arr.length;i++){
for(var j=1;j<arr.length;j++){
highlight(j-1);
highlight(j);
if(arr[j-1] > arr[j]){
visible_swap(arr, j, j-1);
}
yield true;
}
}
yield false;
}
var bubble = bubble_sort(arr)
function gen(){
if(bubble.next()){
setTimeout(gen, 500);
}
else{
alert("Done!");
}
}
这对我来说非常有用,但确实依赖于目前仅在 firefox 上支持的 yield 功能。请注意,要使其正常工作,您需要使用 <script type="text/javascript;version=1.7">。然而,这是完美的。它也可能适用于无限算法,如果需要,它们会徒劳无功。
根据以下答案,我发现的第二个解决方案也有效:
function bubble_sort(arr){
var q = new Array();
for(var i=0;i<arr.length;i++){
for(var j=1;j<arr.length;j++){
q[q.length] = [ [highlight, j-1 ], [highlight, j] ];
if(arr[j-1] > arr[j]){
swap(arr, j, j-1);
q[q.length] = [ [visible_swap, j, j-1] ];
}
}
}
return q;
}
function play(q, step){
if(q.length == 0)
return;
clear_highlights();
cmds = q.shift();
for(ind in cmds){
cmd = cmds[ind];
f = cmd.shift();
f.apply(null, cmd);
}
setTimeout(function(){ play(q, step); }, step);
}
这也有效。这在语法上相当麻烦,但绝对适用于所有浏览器。
尽管如此,似乎有一些javascript“扩展”实现了类似睡眠的语法,这显然比上面所有的都好。谢谢您的帮助!