Max*_*Max 28 javascript ecmascript-6 es6-module-loader
我试过在互联网上搜索导入模块的执行顺序.例如,假设我有以下代码:
import "one"
import "two"
console.log("three");
Run Code Online (Sandbox Code Playgroud)
其中one.js和two.js定义如下:
// one.js
console.log("one");
// two.js
console.log("two");
Run Code Online (Sandbox Code Playgroud)
控制台输出是否保证为:
one
two
three
Run Code Online (Sandbox Code Playgroud)
还是未定义?
McM*_*ath 27
导入的ES6模块以异步方式执行.但是,所有导入都在执行导入的脚本之前执行.这使得ES6模块与Node.js模块或没有该属性的<script>标签不同async.在加载时,ES6模块更接近AMD规范.有关更多详细信息,请参阅Axel Rauschmayer 的探索ES6的第16.6.1节.
因此,在上面提供的示例中,无法保证执行顺序.有两种可能的结果.你可能会看到这个:
one
two
three
Run Code Online (Sandbox Code Playgroud)
或者您可能会看到:
two
one
three
Run Code Online (Sandbox Code Playgroud)
换句话说,两个导入的模块可以console.log()按任何顺序执行其调用; 它们是异步相对于彼此.但它们肯定会在导入它们的脚本之前执行,因此"three"保证最后记录.
也就是说,没有现代浏览器实现ES6模块.我不知道像Babel这样的转发器是否遵循这方面的原始规范.
根据@ BenjaminGruenbaum的评论,我决定更密切地研究这个问题.尽管上面有上述内容,但我无法在规范本身中明确指出模块加载是异步的(尽管可以肯定的是,作为英语母语人士,我发现规范有点难以阅读).如果是这种情况,那么执行导入的顺序将取决于实现.也就是说,同样的结论认为:您不能指望您的进口按任何特定顺序执行.
根据最新规范InnerModuleEvaluation ,由于[[RequestedModules]] 是源代码出现的有序列表,因此module.ExecuteModule()保证了 的顺序。
// 16.2.1.5.2.1 rough sketch
function InnerModuleEvaluation(module, stack, index) {
// ...
// 8
module.[[PendingAsyncDependencies]] = 0;
// ...
// 11: resolve dependencies (source code occurrences order)
for (required of module.[[RequestedModules]]) {
let requiredModule = HostResolveImportedModule(module, required);
// **recursive**
InnerModuleEvaluation(requiredModule, stack, index);
// ...
if (requiredModule.[[AsyncEvaluation]]) {
++module.[[PendingAsyncDependencies]];
}
}
// 12: execute
if (module.[[PendingAsyncDependencies]] > 0 || module.[[HasTLA]]) {
module.[[AsyncEvaluation]] = true;
if (module.[[PendingAsyncDependencies]] === 0) {
ExecuteAsyncModule(module);
}
} else {
module.ExecuteModule();
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
控制台输出始终如下:
one
two
three
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6995 次 |
| 最近记录: |