未加星标

JS引擎、运行时与调用栈概述

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

几乎所有人都已经听说了V8引擎的概念,大多数人都知道javascript是单线程运行的或者说是使用回调队列的。

接下来,我们将详细的讲述这些概念,解释JavaScript到底是怎样运行的。当知道了这些细节后,你就能合理利用已有的API写出更好的,非阻塞的应用。 如果你是JavaScript新手,这篇博客可以帮助你理解为什么相对于其他语言,JavaScript显得如此奇怪。

如果你是比较有经验的JavaScript开发者,希望这篇博客可以让你对你每天使用的JavaScript运行时到底是怎样运行的有一些新的见解。

JavaScript引擎

一个流行的JavaScript引擎是谷歌的V8引擎。例如在Chrome和Node.js中使用的就是V8引擎。下图是V8引擎一个非常简单的预览:


JS引擎、运行时与调用栈概述

V8引擎由两个主要组件所组成: Memory Heap--内存分配区 Call Stack--代码运行时栈

运行时

大部分JavaScript开发者都使用过浏览器的API(例如“setTimeout”)。然而这些API都不是由引擎提供的。 那么,它们来自哪里呢? 真实情况有点复杂。


JS引擎、运行时与调用栈概述

所以除了引擎还有喝很多其他的东西。有浏览器提供的Web API,像DOM,AJAX,setTimeout等等。 然后还有非常有名的event loop和call queue。

调用栈

JavaScript是一门单线程的编程语言,也就是说它只有一个调用栈,因此它只能一次做一件事。

调用栈是一个记录程序运行到哪里的数据结构。调用函数的时候,我们会把它放到栈的最顶部。从函数返回的时候,我们会把它从栈的最顶部弹出来。这就是调用栈做的所有的事情。

我们来看一个例子,看一下如下代码:

function multiply(x, y) { return x * y; } function printSquare(x) { var s = multiply(x, x); console.log(s); } printSquare(5); 复制代码

当引擎开始执行这段代码的时候,调用栈是空的。接下来,每一步如下所示:


JS引擎、运行时与调用栈概述

每次进入调用栈成为栈桢。 这就是当一个异常抛出时,栈的记录是怎样组成的,基本上就是当一个异常发生的时候调用栈的状态。看一下如下代码:

function foo() { throw new Error('SessionStack will help you resolve crashes :)'); } function bar() { foo(); } function start() { bar(); } start(); 复制代码

如果是运行在Chrome中(假定这段代码在foo.js文件中),将会生成如下栈记录:


JS引擎、运行时与调用栈概述

“栈溢出”--这个发生在超过调用栈最大空间的时后。这非常容易发生,特别是当你使用递归但又没有非常严格的测试你的代码的时候。看一下如下代码示例:

function foo() { foo(); } foo(); 复制代码

当引擎开始执行这段代码的时候,首先调用“foo”函数,但是这个函数是递归的,开始调用自己并且没有结束条件。所以每一步执行,相同的函数都会一遍又一遍的加入到调用栈中,看上去就像这样:


JS引擎、运行时与调用栈概述

然而在某个时间点上调用栈中的函数调用数量将会超过调用栈的实际大小,此时浏览器决定采取行动,抛出一个错误,我们就会看到像下面这样的提示:


JS引擎、运行时与调用栈概述

在单线程上运行代码是非常容易的,你不用处理在多线程中发生的复杂的场景--例如死锁。

Concurrency & the Event Loop

在调用栈中存在需要花费很多时间的函数调用时会发生什么呢?例如,想象一下你需要在浏览器中利用JavaScript来做一些复杂的图片转换。

你可能会问--这有什么好问的?问题就是调用栈在执行函数的时候,浏览器不能做其他的事--浏览器被阻塞了。这意味着浏览器将不能渲染,不能运行其他代码,就是说被阻塞了。如果你想要一个体验很好,运行流畅的应用,这将会是很大的问题。

而且还不止这一个问题。一旦你的浏览器在调用栈中处理很多任务,它将会在很长时间内得不到响应,大多数浏览器将会抛出一个错误来采取行动,询问你是否要结束这个web页面。

这不是最好的用户体验,不是吗?

所以,我们怎样才能在运行很重的代码的时候,不阻塞UI,使浏览器不需要等待响应呢?解决方案就是异步回调。

我们将会在下一节详细讲述。

本文翻译自: blog.sessionstack.com/how-does-ja…

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

代码区博客精选文章
分页:12
转载请注明
本文标题:JS引擎、运行时与调用栈概述
本站链接:https://www.codesec.net/view/620976.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(28)