Webpack中import()返回Promise却未呈现异步执行行为问题咨询
问题原因分析
这个打印顺序和Webpack的动态导入配置、项目的Babel转译配置有关,不属于ES标准中import()的默认行为,常见的触发原因有以下几种:
- 你在项目中引入了将动态
import()转为同步require的Babel插件,比如babel-plugin-dynamic-import-node。这类插件多用于兼容SSR、低版本Node运行环境,转换后的import()会变成完全同步的加载逻辑,会阻塞后续代码执行,因此会先完成模块加载、打印Loaded,再执行后续的console.log('Start')。 - 你给当前动态导入添加了Webpack魔法注释,指定了非默认的加载模式:
- 配置
/* webpackMode: "sync" */时,动态导入会被处理为完全同步的逻辑,和静态import行为一致,直接阻塞主线程执行 - 配置
/* webpackMode: "eager" */时,Webpack不会为该模块生成独立的异步Chunk,代码会直接打包到当前Chunk中,加载过程同步执行,仅返回的Promise实例会异步触发回调
- 配置
- 该
intersection-observer模块已经被项目其他位置的静态导入提前引入,模块已经存在于上下文缓存中,import()执行时不需要发起额外的异步资源请求,执行速度极快,再加上浏览器控制台打印存在微小的时序误差,也可能出现你观察到的打印顺序。
验证方法
你可以修改代码在import()的Promise回调中新增打印,确认异步逻辑的实际执行时序:
delete window.IntersectionObserver; if (!('IntersectionObserver' in window)) { console.log(`Load observer`); import('/node_modules/intersection-observer/intersection-observer.js') .then(() => console.log(`Loaded in promise then`)); console.log(`Loaded`); } console.log(`Start`);
如果Loaded in promise then的打印位置在Start之后,说明import()返回的Promise本身还是符合ES异步标准的,只是你写在同级的console.log('Loaded')属于同步代码,会随import()的同步执行部分优先执行。
内容的提问来源于stack exchange,提问作者user3623300
相关产品推荐
相关产品推荐

