异步与同步的含义[关闭]


46

在计算机科学中,异步同步一词的含义是什么?

如果您用谷歌搜索单词的含义,您将获得以下信息:

但是似乎它们被用来传达编程或计算机科学中相反的含义:

HTML异步属性表示即使HTML仍在解析或下载,脚本也将在下载后立即执行,这意味着脚本和HTML都同时存在并同时发生。

这些术语是用来传达计算机科学中相反的意思的吗?


47
我觉得很容易分辨:如果我不理解代码的工作原理,并且如果我在寻找错误时突然发现错误,则该代码可能是异步的。:)
Eric Duminil

4
可悲的事实是,在编程领域中,随着时间的流逝,这些词的含义与它们原本的含义相反。它们当前的含义可能有历史原因,但没有充分的理由。
所罗门诺夫的秘密

3
什么同时,是关键:)
Lightness与莫妮卡赛跑

5
实际操作不会(有必要)在调用函数的同时发生,而操作确实在调用函数的同时发生……对我来说似乎并不落后吗?如果我将函数描述为异步函数,那么我说的是它不能保证在调用它的同时发生。
Affe

2
从语义上来说,“顺序”和“非顺序”可能是更好的选择,但是那艘船已经驶过,驶过。
Jared Smith

Answers:


47

我想给您一个答案,该答案与您找到的那些定义直接相关。当一个任务T1启动第二个任务T2时,它可以通过以下方式发生:

同步:同时存在或同时发生。

因此,保证T2 在T1的时间片内启动和执行。T1“等待” T2的结束,之后可以继续进行处理。从这个意义上讲,T1和T2“同时”发生(不是“并行”发生,而是在连续的时间间隔内发生)。

异步:不存在或同时发生。

因此,T2的执行时间现在与T1无关。它可以并行执行,可能在一秒钟,一分钟或几小时后发生,并且当T1结束时T2仍可以运行(因此,要处理T2的结果,可能需要新的任务T3)。从这个意义上说,T1和T2不是“同时发生(间隔)”。

当然,我同意,当看到当今异步操作通常用于创建并行执行时,字面量定义似乎是模棱两可的。


4
太遗憾了,它有太多的投票,因为我认为这是不正确的。同步方法一个接一个地执行,因为第二个方法必须等待第一个(阻塞)方法完成。这两种方法肯定不会同时执行。
罗伯特·哈维

6
不,我认为我没有。同步和同时性不是一回事。
罗伯特·哈维

1
我愿意断言字典定义对软件开发人员并没有太多用处。尝试将字典定义映射到我们使用的技术术语可能没有用。
罗伯特·哈维

1
无论如何,您的编辑确实可以改善您的描述,但是“同时存在或同时发生”一词会混淆您的描述。同步方法不会“同时执行”;它们以有序的顺序执行,这使它们保持同步。
罗伯特·哈维

1
@RobertHarvey如果使用正确的角度,则字典定义可以很好地工作。你们都沉迷于执行时间。指令的执行期限超出其执行时间。顺序指令同步运动的方式与左轮手枪中子弹同步运动的方式相同。同样,指令可以在指令流水线中同步移动。不再痴迷于执行角度。在执行指令之前,会发生很多废话。
candied_orange

20

我发现理解它的最佳方法如下:

  • 同步:我们知道它何时会发生(它在其他代码结束时发生)。
  • 异步:我们不知道何时会发生。

注意:虽然我们可以安排代码在给定的时钟时间执行,但实际上我们不知道何时会发生,因为它可能会延迟-甚至忽略与系统时钟的混乱-因为系统正忙于做其他事情。此外,即使我们保证它会在给定的时钟时间准确发生,我们也不确定在那个时间执行程序的位置。因此,不可以,为时钟时间安排的代码不是同步的。


请注意,例如,在软件开发中,我们将说任务是异步的,因为该任务是独立的。但是,如果要根据同时发生来定义它,则至少需要有其他东西才能与任务进行比较。

许多平台可以同时执行并行性和任务切换,一些平台具有有限的并行性,有些平台根本不能执行并行性,而仅依赖于任务切换...此外,某些平台无法中断任务,并且必须在执行另一任务之前完成它们...异步任务是对所有这些的抽象,因此系统可以决定如何为给定平台运行任务,而无需开发人员担心它(太多)。

还值得注意的是,我们可以概念化(通常是抽象化),以将外部输入作为异步任务来获取。例如:从用户输入中获取文本。我们不知道用户何时键入。这也适用于从永久存储读取数据,通过网络或任何其他外部系统获取数据。


顺便说一句,尽管有些事情在根本上是异步的,但我们通常可以假装它们不是异步的。为此,我们可以让软件阻止当前执行,而无需执行其他任何操作,直到完成为止。也就是说,我们可以采用异步方式并将其包装在同步API中。

异步API将允许您继续执行,尽管请求的操作尚未完成,而同步API则没有。从那里,您会得到异步的想法-在软件中-意味着同时发生(并发)。

值得注意的是,异步并不意味着并发。在某些情况下,平台只能在当前任务完成后执行异步任务。那将是顺序的(尽管不一定要保证异步任务的执行顺序),不会是并发的(在执行周期中没有重叠),而是异步的。

哦,顺便说一句,在某些平台上,系统可以决定内联异步任务,然后以同步操作的方式在那里执行它(假设它可以,但并非对每个任务都可行)。

同样,异步只是意味着您不知道何时会发生。


您可能还对“并行”执行与“并行”执行之间的区别感兴趣


究竟。OP所找到的描述听起来更多的是关于并行性而不是同步性(如果这是一个词……)。异步与同步是关于动作开始的时间(现在是我调用它,或者稍后是调度程序决定的时间),而并行表示“是的,它们同时发生”与顺序。
Giacomo Alzetta

1
@GiacomoAlzetta我认为这个词是同步的。我也发现了这些相似的词:同步,同步和同步。可能值得提出自己的问题。
Theraot

12

异步:不存在或同时发生。

同步:同时存在或同时发生。

async属性表示即使html仍在解析,脚本也将在下载后立即执行,这意味着两个进程对我而言同时存在。

这确实令人困惑!

考虑替代的含义同步非同步。两件事情都同步,如果一个的定时依赖于其他,和不同步的,如果他们的定时是不相关的。

在您的示例异步工作流中,发生了两件事:脚本执行和html解析。这两件事是不同步的;执行操作的时间和解析操作的时间不相互依赖。如果我们使工作流程同步,则操作将变得同步。说,直到解析明确结束后才开始执行。

但是重要的是要意识到这里实际上存在三种可能性:

  • 执行和解析是真正不同步的;它们可以随时随地以最有效的方式发生。
  • 执行和解析是同步的;也就是说,CPU 在等待I / O完成时不执行任何操作
  • 执行和解析是同步的,但是在等待I / O完成的同时,允许CPU做其他工作,然后在下载完成后返回并进行解析

一旦理解了这一点,流行的编程语言中异步工作流的目的就变得更加清楚:

  • 异步工作流可以帮助我们有效地实现高延迟操作,因为我们不受时间顺序安排无关紧要的事情。如果解析是高延迟和I / O约束的,而脚本执行是高延迟和CPU约束的,则可以通过完全或部分不同步这些操作来获胜。

  • await像C#这样的语言中的运算符是对异步工作流的排序操作。等待是异步等待 ; 这是我们表达一个异步工作流的两个部分之间的排序关系,并说,有一点对的await之前的代码和的await后的代码之间的关系“之前发生”。 这就是我们实现第三个选项的方式

如果这太抽象了,请考虑一些实际示例。当您发送一封信时(一个高延迟的I / O绑定操作),您仍可以在等待答复信件的同时进行CPU密集型工作(例如说数学作业)。数学作业和阅读邮件的操作是不同步的。

但是,假设现在您发送一封信,并且答复中包含您需要纳税的数字。现在,在I / O操作完成之前,您无法执行CPU工作-计算税金。但是,您仍可以在等待时修剪草坪。这是一个异步工作流,已表达了各部分之间的时序关系。


6

我是一名电气工程师,我们处理逻辑电路(逻辑门)中的同步与异步。

假设您有一个AND门(或任何门),它具有两个输入和一个输出。

如果它是异步的,它将在任何输入发生更改时以输出更改的方式更新其输出。这是您的示例的工作方式-您提到的程序。

但是,如果该门还连接有时钟(例如1秒周期的方波),则该时钟会更新每秒的拍数,因为方波从低到高,它是同步的。它与时钟的频率有关。因此它是同步的。您可以将时钟连接到许多电路,并且它们将以有节奏的方式运行-同步。如果您的程序仅检查是否每秒读取一次以运行,那么它也将被同步。


1
像异步/同步串口。
jiwopene

2

想象一下有两个绕地球运行的卫星。

  • 卫星A在地球周围有一个自转周期,因此,地球每旋转一圈,卫星绕地球旋转一圈或少于一圈。
  • 卫星乙的周期旋转的地球周围,从而对地球的每一个完整的旋转,卫星已经绕地球只有一个时间

上例中的卫星B在地球同步轨道上,由

具有与地球自转同步的自转周期

没有人认为卫星A是地球同步的,仅仅是因为它与地球“同时存在或发生”。实际上,卫星B本身也不重要-重要的是与地球自转周期同步的自转周期。这与对象的同时存在无关。这是关于对象之间的关系。保持这个想法。

假设我告诉您系统上的两个线程正在同时运行。线程A(TA)正在获取进程A的数据,线程B(TB)正在获取进程B的数据。我问你,“ TA和TB是否异步?”。您的回答将是:“我怎么知道?我必须看到在各自过程中调用它们的代码。” 我要反驳我的技巧是:“但是我告诉你,TA和TB肯定是同时运行的。”

而你,是相当聪明的个体,会回应,“再一次-他们可能正在运行的同时,但我不知道他们是否正在运行异步至于在调用它们各自的流程TA和TB异步运行。对方真叫没有道理,因为它们不是来自同一过程。”

因此,到目前为止,我们应该直觉,关系的存在在这里很重要,而不仅仅是这两个线程本身的存在。当异步执行的方法,就是我们说的是,该方法的执行确实“ 不是需要同时存在或发生”为调用它的方法的执行。请看以下示例:

func Invoker() {
    DoThis();
    DoThatAsync();

    var foo = CheckThis();
    ... do some work ...
    CheckThat(foo);

    await DoThatAsync();

    CheckThat();
}

从我们之前对卫星的讨论中,“这与物体的同时存在无关;它与物体之间的关系有关。” 这与调用方法和被调用方法的存在无关。它涉及调用者的执行与被调用者的执行之间的关系。如果我们查看系统线程并发现已DoThatAsync()被调用但未执行,则可能是正在等待调度程序或其他I / O,这并不一定意味着调用方法Invoker()未在执行-可以的工作在做。当然,可能在awaiting 时刻DoThatAsync(),但这不能保证。调用其他函数后,情况并非如此-如果它们停止了,Invoker()暂停-无论如何。这是有保证的。Invoker()和调用的同步方法之间的执行“同时存在或同时发生”。


我真的很喜欢 总的来说,相对于定义为“同步”的明确执行路径,这是任意执行的狂野西部
Cruncher

我也认为这是最好的答案。
Barmar

2

具体例子

我想添加一些实际示例,并将它们连接到软件工程世界。首先,考虑一些我希望符合您对“同步”的直观定义的东西:萤火虫在某些情况下闪烁。二,审议通过4X100奥运会女子接力比赛。第三,考虑一下军事电影中的那个老字眼:“男人,同步手表!”

现在,让我们考虑发生了什么。首先,我们观察所有这些东西都是流程,还是随时间扩展的实体。说碗是“同步的”而岩石是“异步的”是没有道理的。其次,探戈需要两个。您不能说“跑步者已同步”。与什么同步?最后,为了使两个进程同时执行某项操作,除非它们已经具有完全相同的频率和相位,否则它们中的一个或两个必须等待

分析

当字典定义说两个同步的实体“同时出现或同时存在”时,这与萤火虫发出的光的概念非常吻合。不幸的是,说灯光是“同步的”是草率地说萤火虫的照明过程是同步的。

那么,一堆萤火虫(大概没有Apple SmartWatch和NTP来引导它们)如何设法同时闪烁其后端?好吧,如果他们有办法设置一致的速度并可以对其进行小的调整,那将非常容易。它们只是闪烁,如果更多的人紧随其后闪烁,它们就会放慢速度(增加延迟),而如果更多的闪烁在眼前,它们就会加快速度(减少延迟)。因此,他们可以使用简单的反馈过程来达到基本相同的速度和相位。这里的重要观察是要注意它们通过等待正确的时刻闪烁来实现同步。

因为你看到的4×100米比赛是有趣的两个在行动过程中形成的时机:在跑步一队是同步的,而运动员在不同的球队是“异步”。接力赛中的第二名选手必须等到第一名选手进入转会区。交接是这两个跑步者之间的同步事件。但是,不同车道中的跑步者不在乎其他车道中正在发生的事情,并且最肯定的是不会放慢脚步并同步进行交接。跑步者的每个泳道相对于彼此都是异步的。同样,我们看到同步需要等待,而异步则不需要。

最后,在一家公司(排,消防支队等)士兵必须同步自己的手表,让他们可以攻击敌人的同时。可能是有些士兵比其他士兵先到达了他们的阵地,或者有机会更快地向敌人开火。但是由于意外因素,同时攻击通常比偶然攻击更有效。因此,为了实现同步,许多士兵必须等待指定的时间行动。

定义特征

为什么这样强调等待?好吧,因为等待是将同步与异步过程区分开的定义功能。如果您有两个完全不了解的进程,则默认情况下应假定它们是异步的。例如,包裹递送和经过的救护车很可能同步。为了证明实际上两个过程是同步的,您需要及时找到一个非常特殊的时刻:同步点

送货司机放下包裹和急救车将某人赶到医院时,通常不会共享我们确定为“同步点”的任何时间点。另一方面,萤火虫每次闪烁时都会同步出现一个同步点,接力赛跑者每次交出指挥棒都会有一个同步点,士兵发动攻击时也会有一个同步点。如果您可以标识一个或多个同步点,则将同步这些过程。这应该很容易理解,因为“ syn-”是希腊语前缀,意思是“ with”或“ together”,而“ chrono”是希腊语 “ time”的。“同步”字面意思是“同时”,

界线

注意,“同步”不一定适用于任何一个或两个过程的整个生命周期。我认为这仅适用于“直到并包括同步点的等待时间”。因此,两个进程可以异步操作,直到它们到达需要通信的状态,然后它们变得同步,交换信息,然后异步继续。一个简单的例子是与某人见面喝咖啡。显然,会议是一个同步点(或多个同步点),两个人到达那个点的事实证明了同步。但是,我们不会说因为两个人见面喝咖啡,所以这两个人一生是“同步的”。也许那是他们一生中唯一遇见的瞬间,否则他们所做的一切都是独立的。

偶然的相遇也不是同步的。如果两个陌生人在大街上经过,那么他们有时在特定位置的事实并不能证明是同步的。一个人坐在长椅上等待公共汽车,而另一个人正走过去的事实也没有。流程只有在满足特定目的时才是同步的。

软件连接

现在,让我们考虑一下软件中的一个非常基本的任务:读取文件。您可能知道,大容量存储通常比高速缓存或主内存慢数千到数百万倍。因此,操作系统和编程语言库通常提供同步和异步I / O操作。现在,即使您的程序只有一个线程,出于讨论的目的,您也应该将OS视为“单独的进程”。

同步

当您进行“同步I / O读取”时,您的线程必须等待,直到数据可用为止。这非常像接力运动员将接力棒交给下一个接力棒,但可以想象接力赛中只有两个赛跑者一直沿着赛道前进,而第二个赛跑者也将接力交还给第一个。

在这种情况下,您的程序线程和OS I / O进程不是“同时发生(起作用)”,因此似乎奇怪地说这些进程是“同步的”。但这是错误的观察方式!这就像在说:“接力队的跑步者不在同一时间跑步,因此他们没有同步。” 实际上,这两种说法都是错误的!在接力队的选手必须在同一时间运行,但只能在一个非常特殊的时刻:指挥棒的手断。实际上,只有在比赛中的这一特殊时刻,我们才相信接力车队是同步开始的!如果我们将I / O请求和响应视为“警棍”,

另一方面,如果我们考虑一台超级计算机上的“有限元分析”之类的事情,就会发现成千上万的进程必须步步为营,才能更新庞大的全局状态。即使某些节点在给定的时间步长之前完成其他工作,它们也都需要等待该时间步长完成,因为结果会通过空间传播到邻居。这种同步就像萤火虫一样:所有演员都在执行相同的任务。

工艺种类

因此,我们可以发明一些术语来帮助我们了解发生了三种情况:“同质同步”,“异质同步”和“顺序同步”。因此,当演员同时执行同一任务(FEA,萤火虫)时,它们是“同质的”。当他们同时执行不同的任务(士兵奔跑,爬行,游泳到目的地,物理,声音,游戏中的AI线程)时,它们是“异构的”。当他们一次执行一个任务时,它们是“顺序的”(中继运行程序,阻止I / O)。它们的外观可能有很大不同,但是它们具有一个共同的属性:所有类型的参与者都进行一些等待,以确保每个人都同时到达同步点。 在同步点之间,或“执行相同动作”与同步性无关。

GPU中的渲染管线是同步的,因为它们都必须一起完成框架,并一起开始新的框架。他们是同质的,因为他们从事的是相同种类的工作,而且他们一起活跃。但是服务器的主要游戏循环和处理远程输入的阻塞I / O线程是异类的,因为它们执行的工作类型非常不同,并且某些I / O线程根本不会做任何事情,因为不是全部使用连接。即使如此,它们仍是同步的,因为它们必须原子共享状态(玩家不得看到部分游戏世界更新,服务器也只能看到玩家输入的一部分)。

异步

现在,让我们考虑“异步I / O读取”。当您的程序向操作系统发送请求以从存储中读取一些数据时,调用将立即返回。让我们忽略回调,而将重点放在轮询上。通常,就程序线程而言,数据可用于程序的时间并不对应于任何特殊的时间点。如果您的程序没有明确等待数据,那么线程甚至将不知道确切的时间。它只会在下次检查时发现数据正在等待。

在操作系统和程序线程同意移交数据的情况下,没有特殊的开会时间。他们就像两艘飞船在夜里经过。异步的特点是没有等待。当然,毕竟,程序线程通常通常最终会等待I / O操作,但不是必须的。在进行I / O提取时,它可以愉快地继续进行其他计算,并且仅在以后有空的时候再检查。当然,一旦操作系统完成数据提取,它也不会等待。它只是将数据放在方便的地方并继续其业务。在这种情况下,就像程序将警棍交给操作系统,然后OS随即出现,将警棍与数据一起放到地面上,然后离开轨道。该程序可能正在或可能不在等待接收切换。

平行性

当我们在软件中将功能标记为“异步”时,通常意味着我们需要并行处理。但是请记住,并行性并不意味着同步。萤火虫是一个很好的例子,因为它们也同时表现出同步和异步行为。尽管大多数苍蝇一致地闪烁,但许多苍蝇显然与该群中的其他鸟格格不入,并且更加随机地闪烁。苍蝇可能同时行动,但并没有全部同步

现在,当我们将某些代码标记为“异步”时,它看起来很有趣,因为这意味着未标记的其余代码为“同步”。那有什么意思?我们不是坚持认为“同步”需要两个探戈吗?但是,如果我们谈论的是在单个线程中执行代码怎么办?在这种情况下,我们需要退后一步,将程序视为一系列状态以及这些状态之间的转换。程序中的语句导致状态转换。我们可以将其视为以该语句开始和结束的“微过程”。实际上,由该语言定义的顺序点是这些“微过程” 的同步点。因此,我们可以查看单线程,

编程语言的完整性保证了状态更新不会跨语句干扰,并且顺序点定义了不允许编译器进行可观察的优化的边界。例如,语句中表达式的求值顺序可能未定义或未指定,从而使编译器可以自由地以各种方式优化语句。但是到下一条语句开始时,如果PL本身是正确的,则程序应处于定义良好的状态。

到现在为止,应该清楚“异步”的含义了。这恰好意味着代码块内的隐含同步契约将被异步块免除。允许独立更新程序状态,而无需顺序(完全一致,同步)的计算模型通常暗示的安全性保证。当然,这意味着我们需要特别小心,不要以不一致的方式破坏程序状态。这通常意味着我们引入了有限的显式同步来与异步块协调。注意,这意味着异步块既可以是异步同步在不同的时间!但是回想起同步只是表明同步点的存在,我们应该毫不费力地接受这个概念。


您可以在此处删除所有示例,除了中继竞赛(它清楚地说明了同步和异步的软件概念,而其他则没有),您的答案将大大改善。
罗伯特·哈维

我认为其他示例说明了同时行动与异构行动,我认为这引起了OP的大部分混乱。
割草机人

1

考虑它的一种方法是SIMD指令,例如AVX。这是一些如何使用它们的示例

同步SIMD指令允许您通过对多个数据执行单条指令,在同一线程中精确地同时执行多个计算。

异步多线程允许您在“可能”,“有点”,“相似”的时间进行多次计算。

结合以下定义:

同步形容词同步 \siŋ-krə-nəs,sin-

1:恰好在同一时间发生,存在或发生[强调我的]

异步形容词asyn·chro·nous | \(ˌ)ā-ˈsiŋ-krə-nəs,-ˈsin- \

1:[...]:不同步


1

一个让我理解“同步”,“异步”与“多线程”之间的区别的类比是厨房的厨师。

假设您正在制作意大利面。您需要执行三个步骤:

  1. 将意大利面煮沸并沥干
  2. 准备酱汁
  3. 混合意大利面和酱汁

同步方法。在同步方案中,只有一个人(线程)按顺序执行所有工作。首先,您将意大利面煮沸,然后站在那儿看着它沸腾。然后将其沥干并放在一旁。然后,准备酱汁。准备好酱汁后,您可以将意大利面与酱汁混合,然后准备好菜肴。这里的问题是效率低下。因为您以同步的方式顺序工作,所以在面食沸腾时就不能加工酱汁。因此,这使您浪费时间,并且在准备酱汁时,您的面食变冷了。

异步方法。在这种情况下,仍然只有一名厨师(线程),但是当面食沸腾时,您可以自己煮酱。将意大利面煮沸后,您需要called-back先将调味料沥干,然后再将called-back其调味。现在,这种方法更加有效,因为您节省了时间,而您的意大利面不必等待那么长时间。

多线程方法。现在,假设您雇用了一位新厨师。现在您有两个厨师(线程)。一位厨师煮意大利面时,另一位厨师煮酱。在这种情况下是否有必要?不可以,因为制作面食非常简单,可以通过异步方法高效进行。而且,管理多个厨师是额外的开销。但是,如果您要一次制作更复杂的菜肴或更多菜肴,那么多位厨师会很有用。


这实际上是一个很好的类比。
罗伯特·哈维

0

一个好问题,经常以不同的方式使用这些术语会引起混乱。

我的回答是这些术语是相对的,它们相对于的是正在执行的主程序(有时甚至是线程)。

这些术语指定了有关程序的内部操作和时序的信息,涉及消息是以阻塞方式(同步)还是以非阻塞方式(异步)发送或接收。如果(主)线程被发送或接收阻塞,则为“同步”,如果以某种方式可中断,则为“异步”。重申一下,这些术语是指既能(正常)工作又能处理事件的实现。

(恕我直言,当然)一旦有消息通过,就不会出现同步与异步之类的事情。在消息传递中,有一个发送者和一个接收者,它们每个都可以有彼此独立的同步或异步实现,但是一旦消息在线上,它就只是一条消息,不再是同步或异步。我们可以将消息分类为请求消息或答复消息或单向消息,但与同步和异步正交(指的是实现是阻塞等待还是可以以某种方式中断)。


非阻塞不同于异步,
user207421

1
@ user207421,请详细说明,因为在这种情况下,我称它们为同义词
Jacob Raihle,

0

“同步”是指两个事件同时发生-但是哪个事件呢?

当我们说“同步执行”时,是指调用者和被调用者正在同时执行(即在堆栈上)。这可能就是您所追求的意思。

当我们说“同步逻辑门”时,是指逻辑门与cpu时钟同步。

当我们在分布式系统的上下文中说“同步模型”时,我们的意思是所有节点都在锁步中执行他们的程序,并且保证在步骤n中发送的消息到达步骤n + 1的开始。

当Java语言规范说一个线程与另一个线程“同步”时,这意味着不同线程中的动作“同时”发生(相对于关系发生之前的发生)。当他们说两个线程“同步对一个对象的访问”时,实际上是指这些线程彼此同步以确保它们永远不会同时在该对象上工作。

...而且我很确定您可以在更多上下文中使用该词,因为“事物同时发生”是一个很普遍的想法:-)


0

我认为您的困惑的关键可以归纳为:

async属性意味着即使html仍在解析,脚本也将在下载后立即执行。

要意识到的是,这句话没有意义,因为它描述了一种不可能的情况。如果HTML仍在解析,则脚本下载过程即使是异步的也不会开始

在编程中,同步意味着:

在执行逻辑时,您感兴趣的所有数据已经​​存在于内存中

异步意味着:

您感兴趣的某些数据尚不存在,仅在将来的某个时间存在

确实,异步编程的这个不存在的方面通常会使人们感到困惑。

暂停html解析,然后下载脚本,脚本下载完成后执行脚本,然后html解析继续,通常如何加载脚本。html解析和脚本执行发生在“相同”时间(相同时间意味着在一起,而不是同时发生)。

如何async脚本加载是HTML看到脚本标签,然后记得下载脚本的未来,但继续进行解析。html解析不会为脚本下载而暂停。稍后,在html解析完成之后,将下载并执行所有异步脚本。html解析和脚本执行不会同时发生(同样,同一时间意味着一起,在这种情况下,它们是分开执行的)。

总结一下:

  • 同步脚本与html一起解析。

  • 将来会分别解析异步脚本。

因此,该async属性的定义不是脚本一旦下载即立即执行-对于同步脚本和异步脚本都是如此。异步的定义是html解析不等待脚本下载

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.