为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候JavaScript是同步的?

什么时候JavaScript是同步的?

什么时候JavaScript是同步的?我一直有这样的印象,因为JavaScript总是异步的。然而,我已经了解到,在某些情况下,它不是(即DOM操作)。什么时候是同步的,什么时候是异步的,有什么好的参考吗?jQuery对此有影响吗?
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

JavaScript总是同步的和单线程的.如果要在页面上执行JavaScript代码块,那么当前将不会执行该页面上的其他JavaScript代码块。

JavaScript只是异步的,例如,它可以进行Ajax调用。Ajax调用将停止执行,其他代码将能够执行,直到调用返回(成功与否),此时回调将同步运行。此时没有其他代码正在运行。它不会中断当前正在运行的任何其他代码。

JavaScript计时器使用相同的回调操作。

将JavaScript描述为异步可能具有误导性。更准确的说法是,JavaScript是同步的,具有各种回调机制的单线程。

jQuery在Ajax调用上有一个选项,可以同步地(与async: false备选方案)。初学者可能会不正确地使用它,因为它允许一个更传统的编程模型,而人们可能更习惯它。有问题的原因是这个选项会阻止页面上的JavaScript,直到它完成,包括所有的事件处理程序和计时器。


查看完整回答
反对 回复 2019-06-26
?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

JavaScript是单线程的,具有同步执行模型。单线程意味着一次执行一个命令。同步意味着一次执行一行代码,即为了代码的出现而在时间上执行一行代码。因此,在JavaScript中,一次只发生一件事。

执行上下文

JavaScript引擎与浏览器中的其他引擎交互。在JavaScript执行堆栈中,底部有全局上下文,然后当我们调用函数时,JavaScript引擎会为各自的函数创建新的执行上下文。当被调用的函数退出时,它的执行上下文将从堆栈中弹出,然后下一个执行上下文被弹出,以此类推。

例如

function abc(){
   console.log('abc');}function xyz(){
   abc()
   console.log('xyz');}var one = 1;xyz();

在上面的代码中,将创建一个全局执行上下文,并且在此上下文中var one它的价值是1.当调用xyz()调用时,将创建一个新的执行上下文,如果我们在xyz函数中定义了任何变量,这些变量将存储在xyz()的执行上下文中。在xyz函数中,我们调用abc(),然后创建abc()执行上下文并放到执行堆栈上.现在,当abc()完成其上下文从堆栈中弹出,那么xyz()上下文从堆栈中弹出,然后全局上下文将被弹出.

现在是关于异步回调;异步意味着一次不止一个。

就像执行堆栈一样,事件队列..当我们希望得到JavaScript引擎中某些事件的通知时,我们可以监听该事件,并将该事件放在队列中。例如,Ajax请求事件或HTTP请求事件。

每当执行堆栈为空时(如上面的代码示例所示),JavaScript引擎会定期查看事件队列,并查看是否有任何事件需要通知。例如,队列中有两个事件,一个Ajax请求和一个HTTP请求。它还想看看是否有一个函数需要在该事件触发器上运行.因此,JavaScript引擎会收到关于事件的通知,并知道要在该事件上执行的相应函数.因此JavaScript引擎调用处理程序函数,在示例中,例如AjaxHandler()将被调用,就像调用函数时一样,它的执行上下文被放置在执行上下文中,现在函数执行完成,事件Ajax请求也从事件队列中删除.当AjaxHandler()完成时,执行堆栈是空的,因此引擎再次查看事件队列,并运行HTTP请求的事件处理程序函数,这是队列中的下一个。重要的是要记住,只有在执行堆栈为空时才会处理事件队列。

例如,参见下面解释Javascript引擎执行堆栈和事件队列处理的代码。

function waitfunction() {
    var a = 5000 + new Date().getTime();
    while (new Date() < a){}
    console.log('waitfunction() context will be popped after this line');}function clickHandler() {
    console.log('click event handler...');   }document.addEventListener('click', clickHandler);waitfunction(); //a new context for this function is created and placed on the execution stackconsole.log('global context will be popped after this line');

<html>
    <head>

    </head>
    <body>

        <script src="program.js"></script>
    </body></html>

现在运行网页并单击页面,然后查看控制台上的输出。输出将是

waitfunction() context will be popped after this lineglobal context will be emptied after this line
click event handler...

JavaScript引擎正在同步运行代码,正如在执行上下文部分中所解释的那样,浏览器正在异步地将内容放入事件队列中。因此,需要很长时间才能完成的函数可以中断事件处理。JavaScript以这种方式处理浏览器中发生的事件,如果需要运行侦听器,则当执行堆栈为空时,引擎将运行它。事件是按照它们发生的顺序来处理的,所以异步部分是关于引擎外部正在发生的事情,即当这些外部事件发生时,引擎应该做什么。

所以JavaScript总是同步的。


查看完整回答
反对 回复 2019-06-26
?
慕的地10843

TA贡献1785条经验 获得超8个赞

JavaScript是单线程的,并且一直在执行正常的同步代码流。

JavaScript可以具有异步行为的好例子是事件(用户交互、Ajax请求结果等)和计时器,基本上是随时可能发生的操作。

我建议你看一看以下文章:

这篇文章将帮助您理解JavaScript的单线程性质、定时器如何在内部工作以及异步JavaScript执行是如何工作的。


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 698 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信