如何将async函数返回值赋值给全局变量players和currentPlayer?
解决方案
你现有代码的核心问题是:把players赋值成了Promise对象(立即执行的async函数返回值默认是Promise),直接取players[0]会报错,且currentPlayer的赋值时机过早——在玩家数据还没真正获取到就执行了。要实现全局变量+异步初始化的需求,按以下步骤修改即可:
1. 先声明全局变量
在代码最外层提前声明全局的players和currentPlayer,暂时不赋值:
let message = document.getElementById('game-message'); // 声明全局变量,后续在异步流程中赋值 let players; let currentPlayer;
2. 重构初始化流程
写一个专门的异步初始化函数,负责调用setPlayers并给全局变量赋值,同时设置初始的currentPlayer:
async function initGame() { // 等待玩家数据获取完成,赋值给全局变量 players = await setPlayers(); // 设置当前玩家为第一个玩家 currentPlayer = players[0]; // 这里可以添加游戏初始化完成后的逻辑,比如显示开始提示 message.innerHTML = `<p>游戏准备完毕!当前玩家:${currentPlayer}</p>`; }
3. 确保setPlayers能正常运行
你的setPlayers依赖getUserInput函数,这个函数必须返回Promise,才能配合await等待用户输入完成。假设通过输入框+确认按钮获取用户输入,getUserInput可以这么实现:
function getUserInput() { return new Promise((resolve) => { // 创建输入框和确认按钮 const input = document.createElement('input'); input.type = 'text'; const submitBtn = document.createElement('button'); submitBtn.textContent = '确认'; // 把元素添加到页面 message.appendChild(input); message.appendChild(submitBtn); // 处理输入确认逻辑 const handleConfirm = () => { const playerName = input.value.trim(); if (playerName) { // 移除元素避免重复创建 input.remove(); submitBtn.remove(); // 返回输入的名字 resolve(playerName); } else { alert('请输入有效的玩家名字!'); } }; // 绑定点击和回车事件 submitBtn.addEventListener('click', handleConfirm); input.addEventListener('keydown', (e) => { if (e.key === 'Enter') handleConfirm(); }); }); }
4. 启动初始化流程
在页面加载完成后调用初始化函数,触发整个流程:
// 页面DOM加载完成后启动游戏初始化 window.addEventListener('DOMContentLoaded', initGame);
完整可运行代码示例
let message = document.getElementById('game-message'); // 全局变量声明 let players; let currentPlayer; async function setPlayers() { message.innerHTML = `<p>请输入玩家一的名字?</p>`; let player1 = await getUserInput(); message.innerHTML = `<p>请输入玩家二的名字?</p>`; let player2 = await getUserInput(); return [player1, player2]; } function getUserInput() { return new Promise((resolve) => { const input = document.createElement('input'); input.type = 'text'; const submitBtn = document.createElement('button'); submitBtn.textContent = '确认'; message.appendChild(input); message.appendChild(submitBtn); const handleConfirm = () => { const playerName = input.value.trim(); if (playerName) { input.remove(); submitBtn.remove(); resolve(playerName); } else { alert('请输入有效的玩家名字!'); } }; submitBtn.addEventListener('click', handleConfirm); input.addEventListener('keydown', (e) => e.key === 'Enter' && handleConfirm()); }); } async function initGame() { players = await setPlayers(); currentPlayer = players[0]; message.innerHTML = `<p>游戏准备完毕!当前玩家:${currentPlayer}</p>`; } window.addEventListener('DOMContentLoaded', initGame);
这样修改后,players和currentPlayer会成为全局可访问的变量,且会在异步获取完玩家信息后正确赋值,setPlayers也能按预期完成玩家名字的收集流程。
内容的提问来源于stack exchange,提问作者NovaBrownie
相关产品推荐
相关产品推荐

