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

为何await在JavaScript类的函数中无法按预期工作?

问题原因分析与解决方案

咱们先拆解一下你遇到的问题:你的代码之所以直接显示3,核心问题在于同步循环和异步操作的执行顺序不匹配。

为什么你的代码会立刻显示3?

  1. 你的run方法里虽然有一个异步立即执行函数,但run本身是同步方法——调用v.run(n)时,会马上执行立即函数里的document.body.textContent = n,然后才进入await sleep(1000)的等待。
  2. 外层的for循环是同步执行的,四次v.run(n)调用会在瞬间完成:n从0到3快速赋值给textContent,所以页面最后会停在最后一次赋值的3,之后四个sleep才各自开始计时,但这时候页面内容已经不会再变化了。

怎么改成预期的依次计数效果?

关键是要让循环等待前一次的异步操作完成后,再执行下一次。我们需要让run方法返回异步操作的Promise,然后在循环里用await等待每次调用完成。

修正后的代码如下:

const sleep = ms => new Promise(res => setTimeout(res, ms));
class K {
  // 把run改成async方法,自动返回Promise
  async run(n) {
    document.body.textContent = n;
    await sleep(1000);
  }
}
var v = new K();

// 用async立即执行函数包裹循环,才能使用await
(async function() {
  for (let n = 0; n < 4; n++) {
    await v.run(n); // 等待当前run的异步操作完成,再进入下一次循环
  }
})();

如果不想修改run的结构,也可以让它返回内部立即执行函数的Promise:

const sleep = ms => new Promise(res => setTimeout(res, ms));
class K {
  run(n) {
    // 返回async函数的Promise
    return (async function() {
      document.body.textContent = n;
      await sleep(1000);
    })();
  }
}
var v = new K();

(async function() {
  for (let n = 0; n < 4; n++) {
    await v.run(n);
  }
})();

这样修改后,代码就会依次显示0,等待1秒后显示1,再等1秒显示2,最后等1秒显示3,和你看到的正常示例效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:30:40