我尝试在互联网上搜索导入模块的执行顺序。例如,假设我有以下代码:
import "one"
import "two"
console.log("three");
one.js
和two.js
定义如下:
// one.js
console.log("one");
// two.js
console.log("two");
控制台输出是否保证为:
one
two
three
还是未定义?
答案 0 :(得分:22)
导入的ES6模块以异步方式执行。但是,所有导入都在执行导入的脚本之前执行。这使得ES6模块与Node.js modules或<script>
tags不同,而不具有async
属性。在加载时,ES6模块更接近AMD specification。有关更多详细信息,请参阅Axel Rauschmayer的探索ES6 的section 16.6.1。
因此,在上面提供的示例中,无法保证执行顺序。有两种可能的结果。你可能会看到这个:
one
two
three
或者您可能会看到:
two
one
three
换句话说,两个导入的模块可以按任何顺序执行console.log()
个调用;它们与彼此是异步的。但它们肯定会在导入它们的脚本之前执行,因此保证最后记录"three"
。
那就是no modern browser implements ES6 modules。我不知道Babel等转发器是否遵循这方面的原始规范。
在下面的@BenjaminGruenbaum's评论中,我决定更密切地研究这个问题。尽管有上述来源,但我无法在specification itself中清楚地说明模块加载是异步的(虽然不可否认,作为英语母语人士,我发现规范有点难以阅读)。如果是这种情况,那么执行导入的顺序将取决于实现。也就是说,同样的结论认为:你不能指望你的进口按任何特定顺序执行。