2

Javascript-单线程,非阻塞,异步,并发语言

 3 years ago
source link: http://developer.51cto.com/art/202101/639976.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

恩,什么?我使用语言来完成工作。对于我和javascript,此过程始于构建一个小型游戏,ajax请求和表单验证。我们与Hapi js的联系越来越深。自从遇到React以来,我一直致力于。现在,要成为一个更好的程序员,您必须问为什么事情如何进行。Javascript运行时对我来说是最大的奥秘之一。

什么是Javascript引擎和运行时?

Javascript运行时是指在运行JavaScript代码时在何处执行。就是说,可以在google chrome上执行javascript,在这种情况下,您的javascript引擎是v8,如果在mozilla上-它是Spidermonkey,如果是IE-那么它的脉轮,如果是Safari-它是nitro,如果在节点上,则是v8。现在什么是JS引擎,什么是JS运行时?

引擎将我们编写的JavaScript转换为机器代码。所有JavaScript引擎都实现ECMAScript提供的语言规范。标准化促进了独立引擎的开发,并确保您的脚本无论在何处运行都可以得到相同的结果。为了获得速度,V8将JavaScript代码转换为更有效的机器代码,而不是使用解释器。它通过像许多现代JavaScript引擎(例如SpiderMonkey或Rhino(Mozilla))一样实现JIT(即时)编译器,在执行时将JavaScript代码编译为机器代码。这里的主要区别是V8不会产生字节码或任何中间码。JavaScript引擎只是更大概念的组成部分。该引擎在称为Javascript Runtime的环境中工作,该环境为我们的脚本提供了附加功能。这些功能可能包括拨打网络电话,捕获鼠标/键盘事件等。

这是JS Runtime的体系结构。V8没有这些WebAPI。这些由运行时给出。在chrome浏览器JS运行时中,浏览器拥有它,而在Node中则由C ++库提供。

qEZjqaF.png!mobile

> Runtime Architecture

让我们看看Javascript是如何异步和单线程的。

单线程,什么?

Javascript代码在单线程中执行,但是Javascript运行时不在单线程中运行。线程池存在于JS运行时中,但是我们不必担心它,因为运行时会处理它。但是,那是怎么做的呢?事件循环可以挽救。

让我们了解什么是运行时(或属于运行时的JS引擎)中的堆和调用堆栈。javascript代码首先转换为机器代码。堆存储所有变量,并由调用堆栈执行操作。

console.log("Start")

function sayHello(name) {

console.log(`Hello ${name}!`)

}

sayHello("Abhinav");

console.log("End")

所有这些都转到调用堆栈并在那里执行。

Start

Hello Abhinav

End

我们可以将脚本分为两种类型,即立即调用和稍后调用。

异步任务到来时会发生什么?任务需要时间才能运行。比如说进行API调用或计时器等。有一个称为回调的概念。这是完成此任务后要执行的功能。

好吧,它们作为任何常规函数进入调用堆栈,但是由于此任务驻留在WebAPI中,因此我们对WebAPI进行了调用。它存储任务的回调函数并为我们完成任务(根据运行时使用线程/多处理)。任务完成后,它将回调发送到回调队列。

在这里再次可视化。

RrAjIbb.png!mobile

现在什么是事件循环?事件循环连续运行(在浏览器运行时中,它并不总是在节点中运行)以检查调用栈是否为空,如果调用栈为空,它将从回调队列中提取第一项并将其移至调用栈并执行回调函数。在堆栈不为空之前,不会从回调队列添加任何功能。

回调总是完全执行的。事件循环一次运行一个回调。没有上下文切换。队列中的所有回调都必须等到当前的回调完成。如果脚本运行时间过长,则会阻止其他脚本。这就是为什么回调应该相对简短而简单。

很简单吧!但实际上,它要复杂得多。有多个队列,具体取决于运行时,并且它们的优先级不同。有一些东西作为渲染队列。谁的工作是渲染屏幕。

非阻塞状态如何?

假设您在调用API时失败,或者发生了其他事件,该事件仍然存在于Web api中,因此它永远不会进入回调队列,因此不会进入调用堆栈。因此,没有任何东西被阻止。

它是并发的吗?

并行和并行有什么区别?并行是您同时执行2个任务的位置。(边吃爆米花边看电影)。这是通过多核来实现的。JS代码在调用堆栈中并行执行,而不是并行执行。但是WebAPI可以利用多核并并行运行。

(本文由闻数起舞翻译自391 Followers的文章《Javascript — single threaded, non-blocking, asynchronous, concurrent language》,转载请注明出处,原文链接:https://theflyingmantis.medium.com/javascript-single-threaded-non-blocking-asynchronous-concurrent-language-ffae97c57bef)

【责任编辑:赵宁宁 TEL:(010)68476606】


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK