Javascript 异步脚本在延迟后执行

Javascript 异步脚本在延迟后执行,javascript,jquery,asynchronous,Javascript,Jquery,Asynchronous,理想情况下,我希望以HTML顺序异步加载所有脚本。据我所知,async不是那样工作的 使用以下属性,general.min.js和funcs.min.js脚本不会运行,因为其中包含一些jQuery 我知道该属性只影响下载,而不影响脚本的执行 那么,下载后如何保持执行顺序呢?如果您希望脚本异步下载但仍按顺序执行,请使用延迟。渲染不会被阻止,因为在解析文档之前脚本执行不会启动 另一方面,async也将异步下载脚本,但它在下载完成后立即执行的每个脚本。因此,如果在大脚本下面包含一个小脚本,那么

理想情况下,我希望以HTML顺序异步加载所有脚本。据我所知,
async
不是那样工作的

使用以下属性,
general.min.js
funcs.min.js
脚本不会运行,因为其中包含一些jQuery


我知道该属性只影响下载,而不影响脚本的执行


那么,下载后如何保持执行顺序呢?

如果您希望脚本异步下载但仍按顺序执行,请使用
延迟
。渲染不会被阻止,因为在解析文档之前脚本执行不会启动


另一方面,
async
也将异步下载脚本,但它在下载完成后立即执行的每个脚本。因此,如果在大脚本下面包含一个小脚本,那么小脚本将更快地下载并首先执行

编辑#2(为了清晰起见,编辑#1被#2取代)

当所有脚本都从外部源加载到
中时,使用
延迟
脚本非常有意义。下载是异步的,DOM解析不会被阻止,执行顺序也会得到维护。耶!我将这些称为延迟脚本

但是,
中的内联脚本(
..
)是在DOM解析期间同步下载和执行的,因此它们无法访问延迟脚本(因为这些脚本在DOM解析之后才会执行)

如果内联脚本需要访问库脚本,如jQuery或lodash,该怎么办?显然,那些库脚本必须在内联脚本运行之前完全下载并执行。这是通过将库脚本放入
而不使用
延迟
来完成的。这使它们立即按顺序执行。请注意,延迟脚本也可以访问库脚本,因为它们甚至在内联脚本之后加载

呸!下面是一个例子:

<head>
    <!-- Executed last: defered scripts -->
    <script src="scripts/general.min.js" defer></script>
    <script src="scripts/funcs.min.js" defer></script>

    <!-- Executed first: library scripts, such as jquery, lodash, etc.. -->
    <script src="scripts/jquery.min.js"></script>
</head>

<body>
    <!-- Executed second: inline scripts -->
    <script>
        $.ready(console.log);
    </script>
</body>

$.ready(console.log);

只需添加一项:延迟的脚本不需要
加载
侦听器(或
$.ready
等),因为DOM已经加载了

切勿将
async=“true”
放在具有依赖项的库上,例如jQuery。如果你想优化你的JS,最好缩小并捆绑在一起,而不是使用延迟加载。除非你的库像Dojo一样自己加载。@RoryMcCrossan我在生产中已经删除了它。我这样做是因为我试图减少渲染阻塞。然后我遇到了这个问题。
defer
async
异步下载脚本,但是
defer
等待DOM被完全解析,然后执行保持顺序不变(
async
将在下载完成后立即执行,无论顺序如何)我也会在这里删除它,因为问题是,通过延迟执行,您不再保证jQuery将首先加载。因此,如您所发现的,如果先加载依赖脚本,就会出现错误。正如我前面提到的,缩小/捆绑是生产环境中最可行的JS优化。我在文档正文中有一些脚本标记没有执行,因为jQuery被延迟了。注意:“
async
defer
需要外部源,因此内联脚本不能有这些属性,所以不可能使用“不带async或defer的脚本标记”。@JustCarty:你完全正确。我想我只是用一种令人困惑的方式解释了一下:)谢谢你的反馈!当我有机会的时候,我会修改我的答案使它更清楚。