必须用 async IIFE 而非普通 IIFE,因其支持 await 等待异步配置加载、自动返回 Promise 便于统一处理,同时保留作用域隔离;普通 IIFE 同步执行,无法等待 fetch、localStorage 读取等异步操作。

用 async IIFE 在模块化落地前动态注入异步配置,本质是借力 JavaScript 原生执行机制,在全局环境初始化阶段完成一次“无感防腐”——既不阻塞主线程,又确保后续逻辑运行在受控上下文中。
为什么必须用 async IIFE 而不是普通 IIFE
普通 IIFE 是同步执行的,无法等待异步操作(如 fetch 配置、读取 localStorage、初始化加密库等)。而现代防腐层常依赖外部数据源或异步就绪的运行时能力。async IIFE 提供了合法语法支持:
- 允许内部使用
await,自然等待配置加载完成 - 自动返回一个 Promise,可被上层统一监听或降级处理
- 仍保持 IIFE 的作用域隔离特性,避免中间变量泄漏到
window
典型防腐层内核注入结构
以下是一个生产可用的骨架,用于在 script 标签执行早期注入带权限校验、API 基址、密钥策略的全局防腐内核:
- 用
(async () => { ... })()包裹整个逻辑,确保立即启动且支持 await - 先尝试从 CDN 或本地缓存加载配置 JSON,失败则 fallback 到硬编码最小集
- 将解析后的配置对象挂载到
window.__ANTI_CORRUPTION__(命名带双下划线强调私有性) - 同时注册拦截器:覆盖原生
fetch、重写XMLHttpRequest.prototype.open,但仅在配置就绪后生效
防错与兼容关键点
这类注入容易在老浏览器或严格 CSP 环境中失败,需主动兜底:
- 包裹 try/catch,捕获网络异常、JSON 解析错误、API 不可用等场景
- 设置超时(如
AbortController),避免因配置服务卡死导致整页白屏 - 判断
globalThis?.window是否存在,兼容 Web Worker 或 SSR 环境(此时跳过注入) - 不依赖
document.readyState,因为 IIFE 在 script 执行时就已触发,早于 DOM 构建
和 ES6 模块共存的实践方式
即使项目已迁移到 type="module",async IIFE 仍有不可替代价值:
- 作为
<script type="module">的前置脚本,提前建立防腐上下文,让模块内代码一上来就能调用window.__ANTI_CORRUPTION__.getApiBase() - 在 legacy 兼容层中(如通过
<script nomodule>加载的 bundle),它是唯一能安全完成异步初始化的方式 - 配合构建工具,可将该 IIFE 提取为独立 entry,生成
anti-corruption.early.js并设defer属性,平衡性能与可靠性

















