如何在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();
关键逻辑说明
- 用
gameLoop递归函数替代原while循环,每次仅执行一轮游戏流程 - 在
fetchColumn的回调里,处理完用户输入、落子、胜负判断后,再调用gameLoop()触发下一轮 - 当
game_over不为0(游戏结束或用户退出)时,递归终止,不再继续执行
这样修改后,程序会等待用户输入完成并处理完当前回合后,才进入下一轮,不会再出现无限循环的问题。
内容的提问来源于stack exchange,提问作者Moeez
相关产品推荐
相关产品推荐

