动态导入 import() 返回 promise,必须显式捕获错误:用 try/catch + await 最清晰,.catch() 适合链式调用与统一上报,可依 error.message 分类处理,并需联动加载状态避免 ui 异常。

动态导入 import() 返回 Promise,网络异常、404、解析失败等都会被拒绝(reject),所以必须显式捕获错误,否则会抛出未处理的 Promise rejection,影响用户体验甚至导致白屏。
用 try/catch + await 捕获最清晰
在 async 函数中使用 await import() 时,所有加载阶段的异常(路径错误、网络中断、模块语法错误、CORS 阻止)都会被 catch 捕获:
- 确保包裹在
async函数内,避免顶层await兼容性问题(除非在 type="module" 脚本中且环境支持) -
catch块收到的error是原生Error实例,包含message和stack,部分浏览器还带cause字段 - 不要只打印日志,建议降级处理:显示友好提示、启用备用逻辑、回退到静态资源或隐藏功能入口
示例:
async function loadChart() {try {
const chart = await import('./charts/BarChart.js');
chart.render(document.getElementById('chart'));
} catch (err) {
console.warn('图表模块加载失败,使用占位图', err.message);
document.getElementById('chart').innerHTML = '
? 图表暂不可用
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
}
}
用 .catch() 处理链式调用更灵活
当不使用 await,而是链式调用 .then() 时,.catch() 必须紧接在 Promise 链末尾,否则中间错误会漏掉:
-
.catch()能捕获import()本身失败,也能捕获.then()回调中抛出的异常(比如模块导出函数执行报错) - 适合需要统一错误上报的场景,例如把
err.stack和模块路径一起发给监控服务 - 注意:不能只写
.then(success).catch(err)就完事,success 回调里仍需防御性检查(如module?.default是否存在)
示例:
import('./i18n/zh-CN.js').then(mod => {
if (typeof mod.load !== 'function') {
throw new Error('语言包缺少 load 方法');
}
return mod.load();
})
.catch(err => {
reportErrorToSentry({
module: 'zh-CN',
error: err.message,
url: './i18n/zh-CN.js'
});
fallbackToEnglish();
});
区分网络层与模块层错误(可选增强)
虽然大多数情况下统一 catch 已足够,但若需精细化策略,可通过 error.name 或 error.message 关键词做粗略分类:
-
TypeError:常见于模块解析失败(如导出语法错误、export default缺失)、跨域限制(CORS)、MIME 类型不匹配(服务器返回 text/html) -
NetworkError/TypeError: Failed to fetch:典型网络中断、404、500、DNS 失败 -
SyntaxError:模块 JS 代码本身有语法错误(通常发生在开发阶段) - 注意:不同浏览器对错误类型的标准化程度不一,生产环境建议以
message包含关键词为主(如'fetch'、'parse'、'CORS')
配合加载状态避免 UI 异常
错误处理不是孤立的,要和加载中、加载完成状态联动:
- 触发
import()前置为“加载中”状态(如按钮禁用、显示 spinner) -
catch中清除 loading 状态,并明确提示用户“重试”或“离线可用功能” - 避免错误后仍保留 loading 态,造成用户长时间等待假象
- 可加简单重试机制(如最多 2 次),但需防重复点击触发多次请求










