You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中如何让程序等待10ms执行TryNumber且不破坏数独求解逻辑

问题原因
  • setTimeout属于异步宏任务,你把逻辑写在setTimeout回调中时,外层同步运行的while循环不会等待回调执行,会瞬间往任务队列塞大量延迟任务。等10ms后回调集中执行时,共享的i、j、number变量已经被循环修改到了最终值,所有回调拿到的都是同一个变量的引用,逻辑完全错乱,才会出现全为1的异常结果。
  • 你虽然给SolveSudoku加了async修饰,但没有使用await等待异步任务执行,函数会直接返回尚未计算完成的数独数组,外层点击回调拿到的也是未完成的结果。
修复方案
  1. 先新增一个延迟工具函数,用来实现可等待的定时效果:
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
  1. 修改SolveSudoku中的循环逻辑,将原本写在setTimeout回调里的代码移到外层,每次循环前用await等待10ms:
async function SolveSudoku(sudoku, sudokuID) {
    let filledNumbers = GetFilledNumbers(sudoku);
    let number, i, j;
    let backtracked = [];
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            temp = '#sudoku' + i + j;
            sudokuID[i][j] = document.querySelector(temp);
        }
    }
    for (i = 0; i < 9; i++) {
        for (j = 0; j < 9; j++) {
            number = 0;
            while (filledNumbers[i][j] == false) {
                // 等待10ms再执行后续逻辑
                await delay(10);
                if (number < 9)
                    number++;
                else {
                    sudoku[i][j] = 0;
                    backtracked = Backtrack(i, j, filledNumbers);
                    i = backtracked[0];
                    j = backtracked[1];
                    number = sudoku[i][j] + 1;
                }

                if (number <= 9 && TryNumber(sudoku, i, j, number)) {
                    sudoku[i][j] = number;
                    sudokuID[i][j].classList.remove("border-red");
                    sudokuID[i][j].classList.add("border-green");
                    break;
                }
                sudoku[i][j] = number;
                sudokuID[i][j].textContent = number;
                sudokuID[i][j].classList.add("border-red");
            }
        }
    }
    return sudoku;
}
  1. 修改button2的点击回调,用async修饰回调函数,通过await等待数独求解完成再更新界面:
button2.addEventListener('click', async function () {
    solvedSudoku = await SolveSudoku(sudoku, sudokuID);
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            sudokuID[i][j].textContent = solvedSudoku[i][j];
        }
    }
})

修改后即可实现每步尝试数字前等待10ms、界面同步更新的效果,求解逻辑也会正常运行。

内容的提问来源于stack exchange,提问作者jonas lemineur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 20:18:04