ES6 导入的定义执行顺序是什么? [英] What is the defined execution order of ES6 imports?
问题描述
我尝试在互联网上搜索导入模块的执行顺序.例如,假设我有以下代码:
I've tried searching the internet for the execution order of imported modules. For instance, let's say I have the following code:
import "one"
import "two"
console.log("three");
其中one.js
和two.js
的定义如下:
// one.js
console.log("one");
// two.js
console.log("two");
控制台输出是否保证:
one
two
three
还是未定义?
推荐答案
JavaScript 模块被异步评估.但是,所有导入都会在模块主体进行导入之前进行评估.这使得 JavaScript 模块不同于 Node 中的常见JS 模块 或 标签 没有
async
属性.JavaScript 模块更接近 AMD 规范它们是如何加载的.有关更多详细信息,请参阅探索的第 16.6.1 节ES6 作者:Axel Rauschmayer.
JavaScript modules are evaluated asynchronously. However, all imports are evaluated prior to the body of module doing the importing. This makes JavaScript modules different from CommonJS modules in Node or <script>
tags without the async
attribute. JavaScript modules are closer to the AMD spec when it comes to how they are loaded. For more detail, see section 16.6.1 of Exploring ES6 by Axel Rauschmayer.
因此,在提问者提供的示例中,无法保证执行顺序.有两种可能的结果.我们可能会在控制台中看到这一点:
Thus, in the example provided by the questioner, the order of execution cannot be guaranteed. There are two possible outcomes. We might see this in the console:
one
two
three
或者我们可能会看到这个:
Or we might see this:
two
one
three
换句话说,两个导入的模块可以以任意顺序执行它们的console.log()
调用;它们相对于彼此是异步的.但是它们肯定会在导入它们的模块主体之前执行,因此 three"
保证最后记录.
In other words, the two imported modules could execute their console.log()
calls in any order; they are asynchronous with respect to one another. But they will definitely be executed prior to the body of the module that imports them, so "three"
is guaranteed to be logged last.
使用 顶级 await
语句(现在在 Chrome 中实现).例如,假设我们稍微修改提问者的例子:
The asynchronicity of modules can be observed when using top-level await
statements (now implemented in Chrome). For example, suppose we modify the questioner's example slightly:
// main.js
import './one.js';
import './two.js';
console.log('three');
// one.js
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('one');
// two.js
console.log('two');
当我们运行 main.js
时,我们会在控制台中看到以下内容(为了说明添加了时间戳):
When we run main.js
, we see the following in the console (with timestamps added for illustration):
[0s] two
[1s] one
[1s] three
自 ES2020 起更新
根据 petamoriken 的回答,从 ES2020 开始,非异步模块的评估顺序似乎得到保证.因此,如果您知道要导入的模块中没有一个包含顶级 await
语句,它们将按照导入的顺序执行.在提问者的例子中,控制台输出总是:
Update as of ES2020
Per petamoriken's answer, it looks like evaluation order is guaranteed for non-async modules as of ES2020. So, if you know none of the modules you're importing contain top-level await
statements, they will be executed in the order in which they are imported. In the case of the questioner's example, the console output will always be:
one
two
three
这篇关于ES6 导入的定义执行顺序是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!