首先,我查看了所有与“睡眠”有关的问题(例如JavaScript版本的sleep()是什么?),但我没有找到可接受的解决方案。
我想制作一个适用于各种算法的视觉教育工具。为此,我使用JavaScript和jQuery来显示数据并美化它。为了启动它,我想做一个排序示例,其中显示一个数组,然后以视觉上令人愉悦的方式进行洗牌和排序。所以我想发生的是两个单元格被突出显示(容易),可能交换(容易),然后在测试下一对之前有一个小延迟(困难)。
我知道JavaScript中没有显式的“sleep”方法。但是,将代码重构为使用setTimeout将意味着递归地重写所有算法,这是一个巨大的障碍(尽管显然不是不可能的)。
作为样本问题,请看一个冒泡排序示例:
这个显然可以通过递归重写来使用setTimeout,但是对于我所想的所有算法来说,这样做需要花费大量时间。我错过了什么吗?有没有一种“简单”的方法可以将实现保留为它们现在的状态,并随意放置睡眠?
编辑: 我找到了两个解决方案:一个漂亮的解决方案和一个兼容性的解决方案。 漂亮的解决方案只在Firefox上有效,不幸的是,并利用了奇妙的yield语义(这里有一些示例说明:https://developer.mozilla.org/en/New_in_JavaScript_1.7)。这完美地解决了我的问题,因此:
这对我非常有效,但需要使用仅在Firefox上受支持的yield能力。请注意,要使其正常工作,您需要使用<script type="text/javascript;version=1.7">。这是完美的。如果需要,它也可以用于无限算法,展示它们的徒劳无功。我发现的第二种解决方案也可以运行,基于下面的回答。
我想制作一个适用于各种算法的视觉教育工具。为此,我使用JavaScript和jQuery来显示数据并美化它。为了启动它,我想做一个排序示例,其中显示一个数组,然后以视觉上令人愉悦的方式进行洗牌和排序。所以我想发生的是两个单元格被突出显示(容易),可能交换(容易),然后在测试下一对之前有一个小延迟(困难)。
我知道JavaScript中没有显式的“sleep”方法。但是,将代码重构为使用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上有效,不幸的是,并利用了奇妙的yield语义(这里有一些示例说明: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“扩展”实现了类似于sleep的语法,显然比以上所有方法都要好。 感谢您的帮助!
setTimeout()
,但这里的OP不愿意(尽管注定要)这样做。 - Pointy