Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
异步Javascript程序如何交互_Javascript - Fatal编程技术网

异步Javascript程序如何交互

异步Javascript程序如何交互,javascript,Javascript,早在web开发的早期,我就学到了一些民间智慧,对于这样的代码 <script src=".../program1.js"></script> <script src=".../program2.js"></script> 据我所知,这是一件好事,因为现在浏览器不需要暂停、下载脚本并执行它。相反,它开始下载脚本,但将继续解析DOM。i、 e.网页在等待javascript下载时不再阻塞。(如果这不是真的,我将感谢您的更正) 然而,更不清楚(也更难测

早在web开发的早期,我就学到了一些民间智慧,对于这样的代码

<script src=".../program1.js"></script>
<script src=".../program2.js"></script>
据我所知,这是一件好事,因为现在浏览器不需要暂停、下载脚本并执行它。相反,它开始下载脚本,但将继续解析DOM。i、 e.网页在等待javascript下载时不再阻塞。(如果这不是真的,我将感谢您的更正)

然而,更不清楚(也更难测试)的是这两个程序是如何相互作用的。它们似乎在相同的共享空间中运行(即,从用户角度来看,javascript仍然是具有两个(全局、函数)作用域的单线程)。然而,在我阅读的文档中,它们的执行顺序似乎没有明确定义

我已经通读了关于的MDN文章。虽然很有趣也很有用,但它并不能完全回答我的问题。据我所知,当浏览器加载
program1.js
program2.js
时,javascript将向事件队列添加一条消息,该消息将在javascript引擎通过事件循环运行时进行处理

我缺少的是,那条信息说了什么?是不是每个程序都有一条消息说“编译并执行所有这些javascript代码”?或者每个程序都会产生多条消息——在我看来,可能是这样的

  • 消息1:从这个程序中提取所有函数并编译它们
  • 消息2:从此程序中提取全局范围内的所有语句和表达式
  • 消息3-n:将每个语句和表达式添加为单独的队列消息,以供以后处理

当浏览器处于处理程序>代码>程序> js<代码>时,会发生什么,但完成下载<代码>程序2> js<代码>?每个程序的语句执行是否可能是交错的

我意识到,作为一名客户机开发人员,这里的最佳实践是不依赖全局作用域,编写每个程序和函数,这样它就不管如何调用,也不会阻塞其他人的代码。然而,我花了很多时间处理其他人的代码,其中一些代码表现不好。我想了解幕后发生了什么,或者这是一种未定义的、独立于引擎的行为,并且不会在实现之间排列

每个程序的语句执行是否可能是交错的

不,绝对不是。JS仍然是单线程的,一个程序在另一个程序之后运行(尽管可能不知道哪个程序先运行)

那个事件循环消息说了什么


这个信息是一个很好的例子。假设脚本解析成功,它将在一次运行中实例化所有声明并计算脚本体。

有两篇文章从实际意义上说明了“async”和“defer”属性(我对浏览器内部结构是绿色的):

从2014年开始,采用优秀+简单的图形:

从2016年开始,为什么异步可能是一种反模式:

异步的 对于您的问题,“异步”指示浏览器执行以下操作:

  • 尽早开始下载此资源
  • 继续前进,您可以同时下载其他资源
  • 但一旦我的下载完成,就停止渲染并尽早开始执行我
  • 实际上,“异步”仍然可以阻止呈现和后续执行,但它允许解析器一直工作到执行开始

    多个异步脚本不能保证它们的执行顺序。这取决于加载的速度。这使得像RequireJS这样的AMD系统可以定义依赖项和回调来异步加载资源,但将它们的执行排队,直到“全局”环境包含所有先决条件,并且执行顺序可以协商(通过rune magic)为止

    推迟 “延迟”的行为如下所示:

  • 尽早开始下载此资源
  • 继续前进,您可以同时下载其他资源
  • 但是一旦我的下载完成,在解析器完成之前什么也不做
  • 现在按照发现的顺序执行所有脚本
  • 一方面,“延迟”更快,因为它永远不会阻止解析器或呈现。但是“延迟”可能会慢一些,因为它必须等到管道清除后才能执行

    这听起来似乎“异步”总是更好,但是如果你用一个快速连接在弱CPU手机上加载2MB的JS,你可能会在解析器完成渲染之前等待10秒执行。使用“延迟”可以防止交互层延迟

    如果你说的是客户端/服务器或客户端应用程序,区别就更模糊了。在像Magento这样的后台应用程序中使用延迟可能更为有利,因为渲染是在服务器端处理的


    在一个完全客户端的应用程序中,在加载JS monolith之前,您可能会得到零内容,因此“延迟”实际上对您没有任何帮助,但如果您的整个应用程序是一个庞大的JS包,并且没有任何并行操作,“异步”也不会。来自:“以依赖于实现的方式,获取ECMAScript源文本(请参阅第10条)以及零个或多个ECMAScript脚本和/或ECMAScript模块的任何相关主机定义值。对于每个此类sourceText和hostDefined,如果sourceText是脚本的源代码,则执行排队作业(“ScriptJobs”,ScriptEvaluationJob,«sourceText,hostDefined»)。[…]感谢Felix!+1提供了有用的信息——然而,由于我对实现javascript引擎没有深入了解,所以还不完全清楚上述规范如何转化为实际的javascript行为。也就是说,在懒洋洋地阅读您的有用评论时,我想知道是否ScriptEvaluationJob最终会为每个加载的jav排队等待额外的消息ascript文件。如果您搜索
    <script src=".../program1.js" async></script>
    <script src=".../program2.js" async></script>