我正在尝试帮助想要在网页上显示随机生成的颜色排序的学生。他的功能是用随机生成的HSL颜色填充全局数组:
function shuffle(array)
{
for(i=array.length-1;i>0;i--)
{
var random = Math.floor(Math.random() * (i+1));
var temp = array[i];
array[i] = array[random];
array[random] = temp;
}
}
另一个功能是在HTML画布上从左到右在数组中显示一系列细的垂直矩形颜色:
function draw()
{
for(d=0;d<361;d++)
{
hue = cArray[d].slice(4,cArray[d].indexOf(",", 4));
ctx.fillStyle = `hsl(`+ hue + `,100%,50%)`;
ctx.fillRect(x,0,4,canvas.height);
x=x+3;
}
x=0; //reset x-coordinate
}
然后是一个包含气泡排序算法的函数:
function bubbleSort(array)
{
for(i=0;i<array.length;i++)
{
for(j=1;j<array.length;j++)
{
var hue1 = array[j-1].slice(4,array[j-1].indexOf(","));
var hue2 = array[j].slice(4,array[j].indexOf(","));
if(Number(hue1) > Number(hue2))
{
var temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
// webpage hangs if function call put here
}
}
}
// webpage works if function call put here
}
如果draw()函数调用位于嵌套循环内,则网页将挂起。但是,如果在循环之后调用draw()函数,则排序完成,并且学生仅看到最终的排序数组。如何暂停循环并间隔调用一次draw()函数,以便排序算法显示该过程?
我看过很多讨论论坛,这些论坛提出了异步和递归解决方案(我只能对此有所了解),但是它们似乎从未应用于嵌套循环。有什么想法吗?
答案 0 :(得分:2)
最简单的方法是制作函数async
(这是ES2017的东西,如果必须针对较旧的环境,则可以转换)。然后,您可以await
进行延迟,以允许浏览器重新绘制画布。使用async
函数可让您继续编写循环,而不是异步回调,同时仍能获得需要在画布上显示内容的异步行为。
这是一个更简单的示例:
const outer = document.getElementById("outer");
const inner = document.getElementById("inner");
function delay(ms) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, ms);
});
}
async function example() {
for (let i = 0; i < 4; ++i) {
outer.textContent = String(i);
outer.className = "cls" + (i % 4);
for (let j = 0; j < 4; ++j) {
inner.textContent = String(j);
inner.className = "cls" + (j % 4);
await delay(200);
}
}
}
example()
.catch(error => {
console.error(error);
});
.cls0 {
color: blue;
}
.cls1 {
color: red;
}
.cls2 {
color: green;
}
.cls3 {
color: black;
}
<div id="outer"></div>
<div id="inner"></div>
问题中的代码正在沦为我所谓的(在我贫乏的小博客上)The Horror of Implicit Globals。您的学生需要声明这些循环计数器。