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

Async/Await异步异常问题:Hangman游戏word值无法正确获取

问题分析

你的判断完全正确,核心就是异步操作的执行顺序问题:

  • fetchWord里的fetch是异步网络请求,它的回调(.then内的逻辑)属于微任务,会排在当前主线程的所有同步代码执行完毕后才触发。
  • 你调用a.fetchWord()后,主线程会立刻继续执行a.displayChoices()和document.write(a.word),此时fetch请求还未完成,this.word还未被赋值,因此页面显示undefined。
  • 用setTimeout能生效是因为它的回调属于宏任务,会在微任务执行完成后才触发,这时this.word已经被成功赋值。
修复方案

方案1:用async/await规范异步逻辑

把fetchWord改为异步方法,调用时用await等待请求完成,再执行依赖单词的逻辑:

<body>
<script>
class Hangman {
  async fetchWord(url) {
    const response = await fetch(url);
    const wordArray = await response.json();
    this.word = wordArray[0];
  }

  displayChoices() {
    const choices = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
    choices.forEach(choice => {
      const label = document.createElement('label');
      label.innerText = choice;
      label.id = choice;
      const element = document.createElement('input');
      element.type = 'radio';
      element.value = choice;
      element.id = choice;
      label.appendChild(element);
      document.body.appendChild(label);
    });
  }
}

(async function() {
  const a = new Hangman();
  await a.fetchWord('https://random-word-api.herokuapp.com/word');
  a.displayChoices();
  // 替换document.write,用DOM元素展示单词更安全
  const wordElement = document.createElement('p');
  wordElement.textContent = a.word;
  document.body.appendChild(wordElement);
})();
</script>
</body>

方案2:在fetch回调内执行后续逻辑

如果不想用async/await,可以把依赖this.word的代码放到fetch的.then回调里,确保单词获取完成后再执行:

<body>
<script>
class Hangman {
  fetchWord(url) {
    return fetch(url)
      .then(data => data.json())
      .then(word => {
        this.word = word[0];
        this.displayWord();
      });
  }

  displayChoices() {
    const choices = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
    choices.forEach(choice => {
      const label = document.createElement('label');
      label.innerText = choice;
      label.id = choice;
      const element = document.createElement('input');
      element.type = 'radio';
      element.value = choice;
      element.id = choice;
      label.appendChild(element);
      document.body.appendChild(label);
    });
  }

  displayWord() {
    const wordElement = document.createElement('p');
    wordElement.textContent = this.word;
    document.body.appendChild(wordElement);
  }
}

const a = new Hangman();
a.fetchWord('https://random-word-api.herokuapp.com/word');
a.displayChoices();
</script>
</body>

额外提示

  • 尽量避免使用document.write,它在页面加载完成后调用会覆盖整个页面,用DOM操作创建元素展示内容更安全可靠。
  • 建议给fetch添加错误处理(比如.catch或try/catch),避免因网络问题导致游戏崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:01:20