为什么说ESModule是异步的?

新手上路,请多包涵

我的理解:ESModule的整个过程虽然划分成了构建、实例化、运行三个阶段,但是在构建阶段还是要去下载对应的RequestedModules,这时js线程会等待这些模块文件下载仍然会阻塞后续代码执行
那为什么说ESModule是异步的呢,求大佬指点

阅读 6.9k
3 个回答

只有过程才可以是“异步”的
所以一个概念,如果它不是一个过程,那么就无所谓“异步”这种说法。你可以说在浏览器中远程加载 ESM 这个过程是异步的,但不能因此就说 ESM 是异步的。

当然是异步的。

前提知识:

1.在游览器渲染进程内,v8和渲染引擎是共用一个主线程的,页面渲染的时候,渲染引擎作为同步任务跑在主线程上面,dom解析标签时,发现了脚本标签,经过解析,游览器会通过特定的io线程发出js资源请求,同时在渲染引擎运行在主线程上时,v8引擎是被挂起的。

2.script标签上有2个属性,分别是defer和async,v8引擎执行js的时机取决于这2个属性,defer属性的效果是,脚本下载与DOM解析并行,只有当DOM解析完毕,才会执行JS内容。async属性的效果是,脚本下载与DOM解析并行,不管DOM是否解析完毕,只要脚本一旦下载完毕,就会执行JS内容。

3.type="text/javascript"时,加载的是脚本,src的文件叫脚本文件;type="module"时,加载的是模块,scr的文件叫模块文件。其中type="module"时,script默认是defer属性的。

然后回到你的问题:为什么esmodule是异步的?

基于前置知识,当页面渲染时,渲染引擎跑在主线程上,v8引擎被挂起,当遇到defer属性的script标签,游览器会启动特定io线程去请求资源,等到下载完毕,产生了一个执行任务的消息,这时如果页面还在渲染,根据defer的特性,v8会继续被挂起,那个执行任务的消息会被丢进消息队列,直到页面渲染完,主线程才会通过事件循环机制去取它,然后调起v8引擎去执行这个消息任务。

既然这个过程满足底层的异步设计,它自然是异步的。

esmodule 在nodejs和Chrome浏览器原生环境中都是提前加载好所有代码才执行的,写业务逻辑根本感受不到异步。
需要构建的esmodule就不是esmodule了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题