浏览器web api在Javascript中运行的位置在哪里?

时间:2018-03-13 19:36:34

标签: javascript multithreading asynchronous settimeout

浏览器web api在哪里运行Javascript,如setTimeout?

他们是在其他环境中运行还是在javascript单线程的帮助下运行?

3 个答案:

答案 0 :(得分:5)

它们在JavaScript运行时之外运行。那些" Web API"在浏览器的Web API执行空间中执行。

例如,

setTimeout()window对象的一种方法(它也可以作为window.setTimeout()调用)。 window不是JavaScript的全部内容(它是浏览器对象),您要求window为您做的任何事情都是在JavaScript运行时和浏览器之外处理的其他能力。 Web API调用的请求源自JavaScript环境,但API调用的执行实际上是在其外部运行。

这就是我们可以在Web应用程序中实现异步行为的原因。虽然JavaScript运行时(这是一个只能一次做一件事的同步环境)正在做一件事,但浏览器可以做其他事情。

setTimeout()alert()navigator.geolocationXMLHttpRequest都是在JS引擎之外运行的Web API的示例。

以下是一些 other Web API's here is a great video ,它们专门针对计时器进行了解释。

答案 1 :(得分:0)

API calls are made发生以下一系列事件:

  • 浏览器进行API调用时,该API调用将放置在调用堆栈中
  • API调用放置在浏览器的Web API堆栈中,以在后台执行
  • 在Web API后台执行API调用时,渲染队列任务通过事件循环传递到调用堆栈(假设调用堆栈中的所有任务均已完成)-这意味着渲染队列未处于主动暂停状态,因此浏览器未冻结
  • API调用完成后,结果将放入回调队列中
  • 如果清除了调用栈,则将API响应的结果放置到调用栈中,并由调用栈执行API响应处理程序

如果需要澄清,请发表评论

答案 2 :(得分:0)

客户端JavaScript中的API:

要了解浏览器API的工作原理,首先,您必须清除关于执行堆栈事件循环消息队列

的概念>

尤其是客户端JavaScript,有许多可用的API-它们不是JavaScript语言本身的一部分,而是基于核心JavaScript语言构建的,为您提供了在JavaScript中使用的额外超能力码。它们通常分为两类:

浏览器API内置于您的Web浏览器中,并且能够公开来自浏览器和周围计算机环境的数据,并使用它来做有用的复杂事情。 例如,Web Audio API提供了JavaScript构造,用于处理浏览器中的音频-获取音轨,更改其音量,对其施加效果等。在后台,浏览器实际上是在使用一些复杂的较低级代码(例如C ++或Rust)来进行实际的音频处理。但是,API再次使您摆脱了这种复杂性。

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction

 <script>
        const second = () =>{
            console.log("How are you doing");
        }
        const first = () =>{
            console.log("Hi there");
            second();
            console.log("The End");

        }
        first();
    </script>

上面的示例是一个同步JavaScript的示例,其中第一个函数被执行,并记录“ Hi There!”。到控制台,调用第二个功能,然后显示“你好吗?”到控制台 然后将“结束”最终记录到控制台,一条指令以同步方式在另一条指令之后。

现在,让我们以setTimeout为例,它是一个Web API。考虑下面的例子

<body>
    <script>
        const second = () =>{
            setTimeout(()=>{
                console.log("Async Hi there");
            }, 2000)
        }
        const first = () =>{
            console.log("Hi there");
            second();
            console.log("The End");

        }
        first();
    </script>
</body>

输出: enter image description here

上面的内容涉及一些异步JavaScript。再次调用第一个函数,记录“ Hi There!”。到控制台,然后调用第二个函数。现在,此函数调用Set Timeout函数,该函数基本上类似于计时器,它将在000毫秒后执行我们传递给它的回调函数。但是,这不会使代码停止两秒钟,而是函数返回,返回到第一个函数并记录“结束”。然后,实际上经过了两秒钟之后,异步“嗨,好!”记录到控制台。 现在,为什么代码继续运行,而不是等待计时器完成?

好吧,在我与您讨论如何在幕后真正发挥作用以及为何在幕后起作用之前,让我快速向您解释另一个示例。假设我们从DOM中选择一张图片,并将其传递给Process Large Image函数, 我们创造的。我们知道此功能将花费一些时间 处理图像。就像我们不希望代码等待之前一样。因此,我们不希望它在图像处理过程中停止, 因为在某些情况下这将是可怕的。我们在这里所做的就是还传入一个Callback函数,我们希望在函数完成处理后立即被调用。就像这样,我们创建了异步代码。

这就是异步JavaScript背后的全部哲学。我们不等待函数完成其工作,然后对结果进行某些处理。相反,我们让该函数在后台执行其工作, 这样我们就可以继续执行代码。然后,我们还传递一个回调函数,该回调函数将在主函数中立即被调用 已经做了它必须做的一切。然后我们继续前进, 这样就不会阻止代码。这意味着它可以保持逐行同步处理代码。因为如果代码实际上被阻止,则在此期间,页面上什么都不会真正起作用。 例如,您不能单击任何按钮或类似的按钮。因此,总而言之,我们可以使用回调函数将操作推迟到将来。

为了使我们的代码无阻塞。但这实际上是如何工作的 JavaScript的背后?嗯,这就是事件循环的所在。当我们调用函数并处理诸如DOM事件之类的事件时,事件循环是JavaScript幕后发生的事情的大图。 事件循环以及Web API,连同执行堆栈和消息队列一起构成了我们的JavaScript运行时。该运行时负责JavaScript在执行我们的代码时如何在后台工作。了解所有这些部分是非常重要的 配合在一起以执行异步JavaScript。

现在让我们看一下上一个示例中的代码 在我们的JavaScript引擎中逐行执行。

首先调用第一个函数,正如我们已经知道的那样, 该函数的执行上下文放在执行堆栈(也可以称为调用堆栈)的顶部。 enter image description here

在下一行代码中,将调用控制台点日志功能,并创建一个新的执行上下文,并将文本记录到控制台。 然后函数返回,执行上下文从堆栈中弹出。00 enter image description here

转到第二个功能,创建一个新的执行上下文 在下一行中,将调用“设置超时”功能。导致又创建了一个执行上下文。

enter image description here

现在,在继续进行操作之前,设置超时功能实际上从何处来?它是 Web API 的一部分。实际位于 JavaScript引擎本身之外。诸如DOM操作方法,设置超时,针对AJAX的HTTP请求,地理位置,本地存储和大量其他内容之类的东西实际上位于JavaScript引擎之外 我们只能访问,因为它们也在JavaScript运行时中 当然,这正是时间将保持异步运行两秒钟的地方,因此我们的代码可以保持运行而不会被阻塞。 enter image description here

当我们调用Set Timeout函数时,将在Web API环境中直接与我们的回调函数一起创建计时器。 它在那里一直保持静止,并以异步方式完成所有工作。

enter image description here enter image description here

不是正确地调用回调函数,而是保持连接到计时器,直到完成为止 而且由于计时器基本上在后台运行,因此我们不必等待,就可以继续执行代码。接下来,Set Timeout函数返回,弹出堆栈,第二个函数的Execution Context也返回,第二个函数现在也返回,我们回到了第一个函数。现在我们将结束记录到控制台 然后我们给自己一个新的执行上下文,将文本打印到控制台,然后再次弹出文本。

接下来,函数返回,我们回到原始状态 现在,我们已经以同步的方式执行了所有代码,并使计时器在后台异步运行。让我们假设两秒钟过去了,计时器消失了。但是我们的回调函数发生了什么嗯,它只是移动到消息队列 执行栈为空后在哪里等待执行 DOM事件就是这样。

对于DOM事件,我们的事件侦听器位于Web API环境中,等待某个事件发生,然后在该事件发生后立即将回调函数放置在Message Queue上 准备执行。

enter image description here

好的,那么如何执行消息队列中的这些回调函数 最后就是事件循环的到来。事件循环的工作是不断监视消息队列和执行堆栈, 并在堆栈为空时将行中的第一个回调函数推入执行堆栈。在这里的示例中,现在堆栈为空,正确,并且我们有一个回调等待执行 事件循环接受回调并将其推入堆栈 为该功能创建新的执行上下文。

这就是事件循环的作用。现在在该回调函数中, 我们只需运行日志功能,即可记录异步“嗨,那里!”到控制台。然后上下文弹出堆栈,我们完成了!现在,如果现在有一些回调在等待,例如从AJAX请求或DOM处理程序返回的数据,那么事件循环将继续将它们推入堆栈,直到所有这些都被处理为止。