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

为何异步IIFE中可调用后声明的箭头函数,外部调用却报错?

为什么调用settingsDataAvailable的时机不同会导致引用错误?

咱们把两种场景的核心差异拆解开来,就能明白为啥一个正常运行、一个报错了:

第一个场景(正常执行)

先看你能正常运行的代码:

(async () => {
  const brwSettings = await brwApi.get(
    ajax_var.resturl + "?_wpnonce=" + ajax_var.restnonce  
  );
  settingsDataAvailable(brwSettings);
})();

const settingsDataAvailable = (data) => {
  console(data);
};

这里的关键是异步函数的执行顺序:

  • 异步IIFE启动后,遇到await brwApi.get(...)会暂停执行,把控制权交回主线程。
  • 主线程继续往下执行,完成const settingsDataAvailable的声明和初始化,这个箭头函数就被正式定义好了。
  • 等brwApi.get的异步请求完成后,异步IIFE才会恢复执行,这时候调用settingsDataAvailable,它已经处于可用状态,自然不会报错。

第二个场景(抛出引用错误)

再看报错的代码:

(async () => {
  const brwSettings = await brwApi.get(
    ajax_var.resturl + "?_wpnonce=" + ajax_var.restnonce
  );
})();
settingsDataAvailable(brwSettings); // 抛出错误

const settingsDataAvailable = (data) => {
  console(data);
};

问题出在同步执行顺序和const的「暂时性死区(TDZ)」:

  • 异步IIFE启动后同样遇到await暂停,交还控制权给主线程。
  • 但主线程接下来直接执行settingsDataAvailable(brwSettings)——这时候const settingsDataAvailable的声明语句还没被执行到。虽然const声明的变量会被提升,但在声明语句执行前,变量处于「暂时性死区」,完全无法访问,所以直接抛出Uncaught ReferenceError。
  • 另外补充:哪怕忽略brwSettings是IIFE内部局部变量导致的未定义问题,光是调用settingsDataAvailable的时机,就已经踩了TDZ的坑。

顺便提一句:const和let声明的变量都有暂时性死区,只有在声明语句执行后,变量才能被正常访问;而var因为没有TDZ,提升时会被初始化为undefined,但咱们用const就得遵守这个规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:35:41