如何在嵌套的for循环中暂停并调用函数?

时间:2019-06-11 17:30:29

标签: javascript function loops nested call

我正在尝试帮助想要在网页上显示随机生成的颜色排序的学生。他的功能是用随机生成的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()函数,以便排序算法显示该过程?

我看过很多讨论论坛,这些论坛提出了异步和递归解决方案(我只能对此有所了解),但是它们似乎从未应用于嵌套循环。有什么想法吗?

1 个答案:

答案 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。您的学生需要声明这些循环计数器。