首页 > 解决方案 > 尝试在递归函数中逐步打印出来,而不是在Javascript中一次全部打印出来

问题描述

我正在尝试制作一个 N-Queens 可视化工具,并将我的求解器连接到 html 文档。我的问题是我试图以 1 秒的间隔逐步显示所有内容,而不是立即显示完成的解决方案。

换句话说,我想展示一步一步完成的每一步。

我的放置功能也连接到 DOM 上的表格,因此当它被放置在板上时,它也会将其放置在 html 表格上。

function place(board, row, col, val, table) {
  const newRow = board[row].split('');
  newRow[col] = val;
  board[row] = newRow.join('');
  //place on DOM as well
  table.childNodes[row].childNodes[col].innerHTML = val;
}

我的求解器的代码是这个

function solver(board, row, col, solutions) {
  if (col === board.length) {
    solutions.push([...board]);
    return;
  }

  const currentTable = listOfTables[solutions.length];

  for (let i = 0; i < board.length; i++) {
    if (canPlace(board, i, col)) {
      place(board, i, col, 'Q', currentTable);
      solver(board, row, col + 1, solutions);
      place(board, i, col, '.', currentTable);
    }
  }
}

我试图在求解器函数中包装一个 setTimeout ,但是当超时达到时,它仍然会一次运行代码。

currentTable 变量用于了解 DOM 中的哪些表当前将被使用。

如果有人需要,这里是带有所有代码的 CodePen https://codepen.io/vvus/pen/KKVKMrq?editors=1111

标签: javascripthtmlrecursiondomtimeout

解决方案


您可以根据自己的喜好调整下面的代码

您将其添加display="none"到所有表中,然后使用此代码在时间间隔内停用该属性

var i=0

setInterval(() => {
          for(z=i;z<listOfTables.length;z++)  {      
    const x=document.getElementsByClassName('new-table')[z]
          if (x.style.display === "none") {
              x.style.display = "";
                       i++                                
          }    
               break  
                       }
            }, 3000);

所以你的最终代码可能看起来像这样

const button = document.getElementById("button-click");
    const selection = document.getElementById("selection");
    let tablesContainer = document.getElementById("tables-container");
    let listOfTables = tablesContainer.childNodes;

    button.addEventListener("click", () => {
      console.log(nQueens(Number(selection.value)));

      listOfTables = tablesContainer.childNodes;
     // add this code to your eventlistner or anywhre you want to show something in time interval
      var i=0
       setInterval(() => {

          for(z=i;z<listOfTables.length;z++)  {      
    const x=document.getElementsByClassName('new-table')[z]

          console.log(z)
          if (x.style.display === "none") {
              x.style.display = "";
                       i++                                
          }    
               break  
                       }
            }, 3000);

    });

    selection.addEventListener("change", (e) => {
      let numOfTables = e.target.value;

      if (numOfTables === 1) numOfTables = 1;
      else if (numOfTables === 4) numOfTables = 3;
      else if (numOfTables === 8) numOfTables = 93;

      const rowsCols = e.target.value;
      for (let allTables = 1; allTables < numOfTables; allTables++) {
        const newTable = document.createElement("table");
        newTable.classList = "new-table";
        newTable.style.display="none"// add this attribute to all your tables
        for (let i = 0; i < rowsCols; i++) {
          const row = document.createElement("tr");

          for (let j = 0; j < rowsCols; j++) {
            const th = document.createElement("th");
            th.innerHTML = ".";
            row.appendChild(th);
          }
          newTable.appendChild(row);
        }
        tablesContainer.appendChild(newTable);
      }
    });

推荐阅读