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

Dijkstra算法网格可视化中setTimeout执行次数异常求助

Dijkstra算法网格可视化动画异常问题求助

我正在实现Dijkstra算法的网格可视化效果:用户点击选择起点和终点节点后,原本应该逐格动画展示所有被搜索到的网格节点,但使用setTimeout实现动画时,仅能绘制4个网格,多数setTimeout调用都被忽略。目前已经能实现一次性绘制所有搜索网格,现在需要解决这个动画异常的问题,附上相关代码及效果说明:

传递起点终点坐标的handleClick函数

function handleClick(event) {
    let xPos = event.offsetX;
    let yPos = event.offsetY;
    let col = Math.floor(xPos / colWidth);
    let row = Math.floor(yPos / colWidth);

    if (selectingStart) {
        context.fillStyle = "rgb(0, 255, 0)";
        context.fillRect(col * colWidth, row * colWidth, 49.5, 49.5);
        startNode = createCoordinate(col, row);
        selectingStart = false;
    } else if (selectingEnd) {
        context.fillStyle = "rgb(255, 0, 0)";
        context.fillRect(col * colWidth, row * colWidth, 49.5, 49.5);
        endNode = createCoordinate(col, row);
        selectingEnd = false;

        dijkstra(startNode, endNode);
        canvas.removeEventListener("click", handleClick);
    }
}

Dijkstra算法核心函数

function dijkstra(startCoordinate, endCoordinate) {
    let pathFound = false;
    let coordinates = [];
    coordinates.push(startCoordinate);
    let timer = 0;

    while (coordinates.length > 0) {

        if (coordinates[0] === endCoordinate) {
            console.log("ENOUGH")
            return true;
        }
        let leftTile = createCoordinate(coordinates[0].xPos - 1, coordinates[0].yPos);
        let rightTile = createCoordinate(coordinates[0].xPos + 1, coordinates[0].yPos);
        let bottomTile = createCoordinate(coordinates[0].xPos, coordinates[0].yPos - 1);
        let topTile = createCoordinate(coordinates[0].xPos, coordinates[0].yPos + 1);

        if (coordinates[0].xPos > 0 && !visitedNodes.has(stringifyCoordinate(leftTile))) {
            if (compareCoordinates(leftTile, endCoordinate)) {
                console.log("ENOUGH")
                return true;
            }

            coordinates.push(leftTile);
            timer++;
            setTimeout(function () {
                context.fillStyle = "rgb(0, 0, 255)";
                context.fillRect((coordinates[0].xPos - 1) * colWidth, coordinates[0].yPos * colWidth, 49.5, 49.5);
            }, 0 + timer * 0)

        }
        if (coordinates[0].xPos < (canvasWidth / colWidth) && !visitedNodes.has(stringifyCoordinate(rightTile))) {
            if (compareCoordinates(rightTile, endCoordinate)) {
                console.log("ENOUGH")
                return true;
            }

            coordinates.push(rightTile);
            timer++;
            setTimeout(function () {
                context.fillStyle = "rgb(0, 0, 255)";
                context.fillRect((coordinates[0].xPos + 1) * colWidth, coordinates[0].yPos * colWidth, 49.5, 49.5);
            }, 0 + timer * 0)
            // alert("FILL");
        }
        if (coordinates[0].yPos > 0 && !visitedNodes.has(stringifyCoordinate(bottomTile))) {
            if (compareCoordinates(bottomTile, endCoordinate)) {
                console.log("ENOUGH")
                return true;
            }

            coordinates.push(bottomTile);
            timer++;
            setTimeout(function () {
                context.fillStyle = "rgb(0, 0, 255)";
                context.fillRect(coordinates[0].xPos * colWidth, (coordinates[0].yPos - 1) * colWidth, 49.5, 49.5);
            }, 0 + timer * 0)
        }
        if (coordinates[0].yPos < (canvasWidth / colWidth) && !visitedNodes.has(stringifyCoordinate(topTile))) {
            if (compareCoordinates(topTile, endCoordinate)) {
                console.log("ENOUGH")
                return true;
            }

            coordinates.push(topTile);
            timer++;
            setTimeout(function () {
                context.fillStyle = "rgb(0, 0, 255)";
                context.fillRect(coordinates[0].xPos * colWidth, (coordinates[0].yPos + 1) * colWidth, 49.5, 49.5);
            }, 0 + timer * 0)
        }
        visitedNodes.add(stringifyCoordinate(coordinates[0]));
        coordinates.shift();
    }
}

效果说明

  • 添加setTimeout前:所有被搜索的网格节点一次性完整绘制
  • 添加setTimeout后:仅绘制4个网格节点,多数搜索节点未被动画展示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:12:52