Async函数未按await预期执行:答题后立即跳转问题求助
问题原因与修复方案
核心问题
- setTimeout调用错误:你在
setTimeout(option.remove(), 3000)里直接执行了option.remove(),这会让移除操作立即触发,而非等待3秒。setTimeout的第一个参数需要是函数引用,不能直接执行函数。 - 异步逻辑未正确等待:
deleteDivs标记为async,但内部的setTimeout没有用Promise包装,导致await deleteDivs()不会等待3秒就直接执行后续代码。 - 不必要的await:
availableQuestions.shift()是同步操作,不需要用await包裹。
修复后的代码
const playTheGame = () => { // 获取所有选项div const divs = options.querySelectorAll('div'); // 遍历绑定点击事件,用forEach更简洁且避免空节点问题 divs.forEach((element, index) => { element.addEventListener('click', async () => { // 标记答案正误 if (index === correct) { console.log('answered correctly!'); element.classList.add('correct'); } else { console.log('answered wrong!'); // 修正原代码的错误提示 element.classList.add('wrong'); // 可选:给错误答案加样式 } // 等待3秒,用Promise实现可await的延迟 await new Promise(resolve => setTimeout(resolve, 3000)); // 清除所有选项div divs.forEach(div => div.remove()); // 移除当前题目并加载新题 availableQuestions.shift(); newQuestion(); }); }); };
关键优化点
- 用
forEach遍历选项div,替代原有的childNodes遍历,避免处理不必要的空节点 - 用
new Promise(resolve => setTimeout(resolve, 3000))实现标准的异步等待,确保后续操作在3秒后执行 - 简化嵌套函数结构,直接在点击事件回调中处理完整逻辑,提升可读性
- 修正了原代码中else分支错误的console.log提示
内容的提问来源于stack exchange,提问作者Stef Verniers
相关产品推荐
相关产品推荐

