【问题标题】:Trying to print out step by step in a recursive function without printing them out all at once in Javascript尝试在递归函数中逐步打印出来,而不是在 Javascript 中一次全部打印出来
【发布时间】:2020-09-21 13:27:00
【问题描述】:

我正在尝试制作 N-Queens 可视化工具,并将我的求解器连接到 html 文档。我的问题是,我试图以 place 函数的每一个 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

【问题讨论】:

  • 一种方法可以将所有移动推入一个数组,然后在最后循环超时。

标签: javascript html recursion dom timeout


【解决方案1】:

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

您将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);
      }
    });

【讨论】:

  • 这有点接近我想要实现的目标,但我真正需要的是显示 place 功能的每一次尝试。所以类似于你给我的解决方案,但专注于 place 功能。
猜你喜欢
  • 2019-04-25
  • 2018-04-10
  • 2020-10-08
  • 2021-07-01
  • 2023-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多