什么真正决定了 JavaScript 模块在 .html 中的执行顺序?

ton*_*120 11 javascript

我读到第一个出现的模块是最先加载的。这不是真的。

在我回答这个问题之前,我学到了:

  1. 首先执行没有导入的模块(叶模块)。
  2. 导入的模块在它导入的模块执行之前不会执行。

这让我可以解释这样的基本场景:

2.js日志2和导出functionTwo(调用时为 logs "2-export")。
1.js记录1和导入并functionTwo2.js.

无论这些模块的源顺序如何,2.js总是先执行,因为1.js之前不能执行2.js——它依赖于2.js向它导出的某些东西。控制台总是显示:'2, 1, 2-export'。


但是,对于这两种情况,这是一个不完整的答案:

  1. ModuleA 从 ModuleB 导入。ModuleB 从 ModuleA 导入。
  2. ModuleA 从 ModuleB 导入。ModuleC 从 ModuleD 导入。我一直在尝试 source-order 并且我无法直观地选择确定模块执行完整顺序的规则。我只知道 D 或 B 必须先执行。(有时先执行 DB 或 BD;有时先执行 DC 或 BA)

ps

我们所说的裁决是否仅适用于没有该async属性的模块?具有该async属性的模块是否真的在加载后立即执行?

Twi*_*her 12

规则非常简单:首先导入依赖树的叶子(它们的代码正在执行),然后是所有中间模块,直到根模块。

这就是您观察到这种行为的原因:

  • 1是一个叶模块,它首先被执行(console.log('1')functionExport声明)
  • 2导入,1因此它在 ( console.log('2'))之后立即执行
  • 2最终从1( console.log('1export')调用函数

所述ES6说明书实际上没有详细说明清楚是否进口应该按顺序或不被处理。一些浏览器可能有顺序导入,而其他一些浏览器可能没有。

如果要保证特定的执行顺序并在浏览器之间具有一致的行为,则必须相应地指定导入链。不能保证两个导入链分别执行(这就是为什么有时您会首先看到 DB,而不是 DC)。不能保证两条导入链按特定顺序执行(这就是为什么您有时会看到 DB,有时会看到 BD)。

唯一有保证的事情是脚本其导入已经执行执行。

关于async属性的最后一句话,它允许在浏览器继续解析页面时推迟获取和执行。它module像普通脚本一样适用于脚本,唯一的区别是它们也加载它们的依赖项,以符合上述规则。