问题描述
我是JavaScript的新手,我正在尝试创建一个可视化气泡排序算法的程序。
这个想法是通过fillRect(x,y,x,y)生成不同大小的矩形,并将高度保存到数组中。会调用bubble-sort函数,并且数组会通过比较高度来对自身进行排序,并且每次在数组中移动高度时画布都会重新绘制自身。
我使功能正常工作。问题是我不知道如何在每次重涂之间创建延迟。目前,它会立即排序,您看不到动画。我想应该使用从java睡眠之类的东西?我不知道。
到目前为止,这是我的代码:
var list = [];
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
var x = 4;
for (i = 0; i < 38; i++) {
var random = Math.floor(Math.random() * (400 - 10) + 10);
bar = ctx.fillRect(x,4,20,random);
list.push(random);
x += 21;
}
function bubbleSort() {
for (let i = 0; i < list.length - 1; i++) {
for (let j = 0; j < list.length - i - 1; j++) {
if (list[j] > list[j + 1]) {
let temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
ctx.clearRect(0,c.width,c.height);
repaint(list);
}
}
}
}
function repaint(list) {
ctx.clearRect(0,c.height);
let k = 4;
for (let i = 0; i < 38; i++) {
ctx.fillRect(k,list[i]);
k += 21;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<Meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>bubble-sort</title>
</head>
<body>
<canvas id="myCanvas" width="805px" height="550px" style="border:2px solid #000000; margin-left:100px; margin-top: 100px; background: gray"></canvas>
<br><br>
<button type="button" onclick="bubbleSort()" style="margin-left: 100px">bubble sort</button>
<script src="bubble.js"></script>
</body>
</html>
解决方法
您可以使用以下延迟功能:
const delay = ms => new Promise(resolve => setTimeout(resolve,ms));
然后将bubbleSort
函数更改为async
,然后在每次迭代后几毫秒内将await
更改为>
var list = [];
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
const delay = ms => new Promise(resolve => setTimeout(resolve,ms));
var x = 4;
for (i = 0; i < 38; i++) {
var random = Math.floor(Math.random() * (400 - 10) + 10);
bar = ctx.fillRect(x,4,20,random);
list.push(random);
x += 21;
}
async function bubbleSort() {
for (let i = 0; i < list.length - 1; i++) {
for (let j = 0; j < list.length - i - 1; j++) {
if (list[j] > list[j + 1]) {
let temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
ctx.clearRect(0,c.width,c.height);
repaint(list);
await delay(200);
}
}
}
}
function repaint(list) {
ctx.clearRect(0,c.height);
let k = 4;
for (let i = 0; i < 38; i++) {
ctx.fillRect(k,list[i]);
k += 21;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>bubble-sort</title>
</head>
<body>
<canvas id="myCanvas" width="805px" height="550px" style="border:2px solid #000000; margin-left:100px; margin-top: 100px; background: gray"></canvas>
<br><br>
<button type="button" onclick="bubbleSort()" style="margin-left: 100px">bubble sort</button>
<script src="bubble.js"></script>
</body>
</html>
如果您不想使用async
await
等,这是一种非常简单的方法。
仅供参考,如果您不能将函数更改为async
,则仍然可以通过阻塞这样的线程来实现它,但是可能会使CPU占用100%的内存,因此不建议这样做:
function delay(ms) {
const target = performance.now() + ms;
while(performance.now() < target) {
}
}