JavaScript:异步加载的脚本,是那些“并行”评估的(竞争条件)吗?

时间:2010-02-05 16:36:00

标签: javascript

鉴于我异步(!!)使用异步脚本加载器(将脚本标记写入文档的头部然后将下载文件)加载多个JavaScript文件,这些脚本是否并行评估?

<script>
 var script = document.createElement('script');
 script.src = "library1.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
 <!-- Other Markup -->
<script>
 var script = document.createElement('script');
 script.src = "library2.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
<!-- Other Markup -->
<script>
 var script = document.createElement('script');
 script.src = "library3.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>

“正常”,当在HTML文档(正文和头部!?)中有标准脚本标记时,浏览器将停止/完成所有其他活动(下载/页面呈现)并仅处理它遇到的单个脚本标记。这导致“序列化”执行,不会导致任何“竞争条件”。

但是通过使用异步加载器技术,插入的脚本标记(在头部中)是否也会导致(最后)到序列化渲染(在下载时),只会评估“当前”脚本或者是否存在是否有可能并行评估其他异步加载的脚本文件,因此容易出现竞争条件?

非常感谢!! 蒂姆

2 个答案:

答案 0 :(得分:5)

虽然脚本将并行下载,但执行的顺序并不确定。 IE将按照他们完成下载的顺序执行它们,而Firefox会按照它们在DOM中附加的顺序执行它们。

这是一个问题。例如,假设使用该技术添加脚本A和脚本B.现在假设脚本A是jQuery,脚本B执行此操作:

$(document).ready(function(){...})

在IE中,如果由于某种原因(例如,网络流量,缓存未命中)脚本B在脚本A之前完成下载,则会被搞砸,因为它将在加载jQuery之前执行。

有关更好的解释,请参阅this article

对于解决方案,您可以改为place the <script> elements as far down the page as possible(例如在结束</body>元素之前。虽然这不能保证并行下载,但它确实有助于缓解解决方案正在解决的“阻塞”问题。

答案 1 :(得分:4)

正如this StackOverflow question所说,Javascript由单个线程执行。因此,您的脚本不可能并行执行。正如Crescent Fresh的答案所指出的那样,你不能依赖于执行它们的命令,但是你可以依赖一个在下一个开始之前完全执行,只要没有该脚本执行setTimeout或其他任何异步操作。