引擎与环境(一):引擎、运行环境、调用栈的概览

519 浏览发布于 作者 zouyang (欢迎转载-请注明出处链接)留下评论分享按钮

1、概览

随着javascript越来越流行,越来越多的团队在各种场景里面使用javascript,前端、后端、hybrid apps、嵌入式设备等等。

通过 GitHut stats我们可以看出js在最活跃github榜单上排名第一。越来越多的项目需要依赖js,越来越多的开发者每日都会跟js打交道。

基本上每个人都听说过V8引擎这个概念,而且都知道js是单线程,并且运用了callback队列。在后面的时间里,我将会对这类诸多概念和机制进行深入的探讨。

这个系列的文章旨在深入javascript,探寻它的深层运行机制。我相信,通过认识javascript的各个功能模块,以及它们是如何协作,我们一定会写出更好的代码与应用。

2、Javascript引擎

一个流行的js引擎,比如谷歌的V8引擎,它被用于chrome浏览器和Node.js的内部,引擎长什么样呢,下图是一个简化的例子:

引擎由2部分构成:
内存堆(Memory Heap)—这就是发生内存分配的地方
调用栈(Call Stack)—这就是代码执行时栈帧(Stack Frame)的位置

3、Runtime运行时环境

Javascript开发者使用了许多浏览器的API (比如 “setTimeout”),然后这些API,不是由js引擎提供的。那么它们是从哪里来的呢?下图是一个简化说明图:

左边的是js引擎,右边是web API 和 事件循环与回调队列。其中,Web APIs 由浏览器提供的,这些功能包括:DOM、AJAX、setTimeout等等。

4、调用栈

js是一个单线程编程语言,意味着它有一个单一的调用栈,因此同一时间只能干一件事。调用栈是一个数据结构,它记录了我们程序当前执行到代码的位置。如果我们运行一个函数,我们会将此函数放到调用栈的最顶部,如果我们return一个函数,就把此函数从顶部移除,这就是栈的用途。让我们看一个例子:


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

当引擎刚开始执行这段代码时,调用栈将会是空的,之后将会一步步执行如下步骤:

每一个被压入栈去执行的代码称为一个栈帧(Stack Frame)。
当异常抛出时,当前执行的栈帧(Stack Frame)将会被追踪到,看看下面代码的执行:


function foo() {
    throw new Error('SessionStack 将会帮助我们解决程序崩溃 :)');
}
function bar() {
    foo();
}
function start() {
    bar();
}
start();

如果上面代码在Chrome浏览器下执行,会抛出如下错误,并显示了出错行:

“Blowing the stack”– 这一切发生在达到调用栈最大值的时候。这种情况可能很容易发生,尤其是当你使用递归并且没有全面地测试这段代码的时候。让我们来看下示例代码:


function foo() {
    foo();
}
foo();

当引擎开始执行上述代码时,会调用foo函数,然后foo函数内部又是调用的它自己,所以就会一直重复调递归用下去。调用栈此时会是这个样子:

在某个时刻,函数调用的数量会超过调用栈的大小,浏览器将会决定采取行动,通过抛出一个错误,看起来像这样:

在单线程中运行代码可以变得很轻松,因为你不必处理在多线程环境中产生的复杂场景 — 例如,死锁
但是在单线程上运行是很受限制的。因为JavaScript只有一个单一的调用栈,当它的运行变慢时发生了什么?

5、并发和事件循环

当你在调用栈上为了处理一个函数调用时花费了大量的时间会发生什么?例如,想象你正在浏览器上用js处理一些非常复杂的图像变换操作。
你可能会问 — 这为什么是一个问题?问题是当调用栈上有函数在执行时,浏览器实际上还不能做其他事 — 因为它被阻塞了。这意味着浏览器不能做渲染,它不能运行任何其他的代码,它只是卡住了。如果你想要在你的应用中有一个流畅的界面,这就产生了问题。
而且这不是仅有的问题。一旦你的浏览器开始在调用栈上处理非常多的事务时,它可能会停止响应很长一段时间。和大多数浏览器一样会引发一个错误,问你是否要终止这个web页面。
现在,这不是最好的用户体验,对吗?
因此, 我们怎样才能在执行大量代码的时候不会阻塞用户界面并造成浏览器的未响应?解决办法是异步回调。
这将在《JavaScript深层工作原理解析(二)》中详细解释:)

想要打赏,请点击这里

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注