从文档就绪事件中导入的模块调用函数是否安全?

Is it safe to call a function from imported module inside document ready event?

我想在呈现 DOM 时从导入的模块调用一个函数。让我怀疑这样做的安全性的是模块文件是异步获取的。因此,我担心的是:是否有可能在文档准备好后获取所需的模块文件?

import someModule from '../someModule.js'

$( document ).ready(function() {
    someModule.hello();
});

这段代码安全吗?

该代码是安全的。

如果 您使用的是 DOMContentLoaded 而不是 $(document).ready,则可能需要担心。模块是异步加载的,模块本身导入的所有内容都在模块主体 运行s 之前加载。即:

import someModule from '../someModule.js'

将首先解析为 someModule 导出的值,然后才将模块的其余部分解析为 运行:

$( document ).ready(function() {
    someModule.hello();
});

文档的其余部分可能在那段时间完成加载,特别是如果依赖树中的导入链更高,并且源 HTML 很短。

但是 $(document).ready 不仅会 运行 文档准备就绪时的回调,还会 运行 文档准备好时的回调文档 已经 就绪 - 可以使用 document.readyState.

检查

示例:

setTimeout(() => {
  // the document will have been fully loaded for ages now,
  // but the callback will still run:
  $(() => {
    console.log('running');
  });
}, 5000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

如果您使用的是 DOMContentLoaded,为了安全起见,您需要使用

if (document.readyState === 'complete') {
  someModule.hello();
} else {
  window.addEventListener('DOMContentLoaded', () => someModule.hello());
}

另请注意,在 jQuery 中,当文档准备好时安排回调的首选现代方法是将回调传递给 $:

$(() => {
    someModule.hello();
});