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

如何在JS的while循环中使用回调时终止无限循环(禁用async/await)

解决Connect4游戏异步输入导致的无限循环问题

你遇到的问题核心是:while是同步循环,会持续执行,但readline.question是异步非阻塞的——调用它后不会等待用户输入完成,代码直接进入下一次循环,因此才会不停重复打印棋盘和提问,完全没机会等待用户输入。

不用async/await的话,直接把同步循环改成递归回调的方式即可,让每一轮游戏流程都在用户输入完成的回调里触发下一轮,具体改法如下:

修改后的完整代码示例

function fetchColumn(player, callback) {
  io.question(`Player ${player}, which Column? `, line => {
    console.log(`You requested "${line}"`);
    chosen_column = line;
    callback(); 
  });
}

let connect4 = new Connect4();
connect4.makeBoard(numRows, numCols, winLength);
let game_over = 0;
let current_player = 1;
let move_status;
let x_in_a_row_status;
let chosen_column;

// 用递归函数替代原while循环
function gameLoop() {
  if (game_over !== 0) return; // 游戏终止则停止递归
  
  connect4.printBoard();
  fetchColumn(current_player, () => {
    console.log(`you entered ${chosen_column}`);
    
    if (chosen_column != 'Q' && chosen_column != 'q') {
      move_status = connect4.place_piece(chosen_column, current_player);
      x_in_a_row_status = connect4.x_in_a_row(current_player);
      
      if (move_status == 0) {
        // 此处编写原Further code逻辑,比如胜负判断、玩家切换
        // 示例:假设达成连线时游戏结束
        if (x_in_a_row_status !== 0) {
          game_over = 1;
          console.log(`Player ${current_player} wins!`);
          return;
        }
        // 切换玩家
        current_player = current_player === 1 ? 2 : 1;
      } else {
        console.log("无效落子,请重试!");
      }
      
      // 处理完当前回合,启动下一轮
      gameLoop();
    } else {
      game_over = 1;
      console.log("游戏已退出!");
    }
  });
}

// 启动游戏循环
gameLoop();

关键逻辑说明

  1. 用gameLoop递归函数替代原while循环,每次仅执行一轮游戏流程
  2. 在fetchColumn的回调里,处理完用户输入、落子、胜负判断后,再调用gameLoop()触发下一轮
  3. 当game_over不为0(游戏结束或用户退出)时,递归终止,不再继续执行

这样修改后,程序会等待用户输入完成并处理完当前回合后,才进入下一轮,不会再出现无限循环的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:30:59