摘要:是如何工作的引擎,運(yùn)行時(shí)以及調(diào)用棧的概述原文譯者隨著變得越來(lái)越流行,團(tuán)隊(duì)在多個(gè)層級(jí)都對(duì)它進(jìn)行利用前端,后端,混合應(yīng)用,嵌入式設(shè)備以及更多。這個(gè)將會(huì)在是如何工作的的第二部分進(jìn)一步解釋。
How JavaScript works: an overview of the engine, the runtime, and the call stack JavaScript是如何工作的:引擎,運(yùn)行時(shí)以及調(diào)用棧的概述
原文:How JavaScript works: an overview of the engine, the runtime, and the call stack
譯者:neal1991
welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me
LICENSE: MIT
隨著JavaScript變得越來(lái)越流行,團(tuán)隊(duì)在多個(gè)層級(jí)都對(duì)它進(jìn)行利用-前端,后端,混合應(yīng)用,嵌入式設(shè)備以及更多。
正如GitHut stats所展示的那樣,JavaScript是Github上面最活躍以及總Push次數(shù)最多的語(yǔ)言。在其它類(lèi)別中也不會(huì)落后太多。
(獲取最新的 GitHub language stats).
如果項(xiàng)目對(duì)于JavaScript越來(lái)越依賴(lài),這意味著為了構(gòu)建好的軟件開(kāi)發(fā)者必須利用這個(gè)JS提供的一切并且對(duì)于生態(tài)系統(tǒng)的內(nèi)部有著更深的理解。
因此,盡管每天有很多開(kāi)發(fā)者在使用JavaScript,但并不知道內(nèi)部到底發(fā)生了什么。
概覽幾乎每個(gè)人都已經(jīng)聽(tīng)說(shuō)過(guò)V8引擎的概念,并且很多知道JavaScript是單線程的或者它是使用一個(gè)回調(diào)隊(duì)列的。
在這篇博文中,我們將會(huì)詳細(xì)講述所有概念并且解釋JavaScript是如何真正運(yùn)行的。在了解這些細(xì)節(jié)之后,你將能夠?qū)懗瞿軌蜻m宜地利用提供的API的更好的,非阻塞的app。
如果對(duì)于JvaScript來(lái)說(shuō)還不是很了解,這篇博文將會(huì)幫助你理解為什么JavaScript和別的語(yǔ)言相比如此“奇怪”。
如果你是一個(gè)有經(jīng)驗(yàn)的JavaScript開(kāi)發(fā)者,希望這篇文章能夠讓你對(duì)你每天使用的JavaScript Runtime是如何真正工作的。
JavaScript 引擎最流行的JavaScript引擎的例子之一就是谷歌的V8引擎。比如Chrome以及Node.js內(nèi)部就是使用V8引擎。下面是一個(gè)簡(jiǎn)單的視圖示例:
引擎主要由兩個(gè)部分組成:
內(nèi)存堆——這是內(nèi)存分配發(fā)生的地方
回調(diào)——這是你代碼執(zhí)行時(shí)的棧幀。
Runtime有很多瀏覽器中的API幾乎都被JavaScript開(kāi)發(fā)者使用過(guò)(比如:"setTimeout")。然而這些API并不是由引擎提供的。
那么,它們是從哪來(lái)的呢?
事實(shí)證明這有一點(diǎn)復(fù)雜。
因此,雖然我們有引擎但實(shí)際上是有更多。我們有那些由瀏覽器提供的Web API,像DOM, AJAX, setTimeout以及更多。
接著,我們還有非常流行的事件循環(huán)(event loo)以及回調(diào)隊(duì)列(callback queue)。
調(diào)用棧JavaScript是一種單線程的編程語(yǔ)言,這意味著它只擁有一個(gè)多帶帶的調(diào)用棧。因此它一次只能做一件事情。
調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu)記錄著我們正在程序的什么地方。如果我們步入一個(gè)函數(shù),我們就將這個(gè)函數(shù)放在棧的頂部。如果我們從一個(gè)函數(shù)返回,我們則是將這個(gè)函數(shù)從棧頂彈出。這就是這個(gè)棧所做的一切。
讓我們看一個(gè)例子。參看如下代碼:
function multiply(x, y) { return x * y; } function printSquare(x) { var s = multiply(x, x); console.log(s); } printSquare(5);
當(dāng)引擎執(zhí)行這段代碼的時(shí)候,調(diào)用棧首先將會(huì)是空的。然后,將會(huì)按照以下步驟進(jìn)行:
調(diào)用棧中的每一項(xiàng)都被稱(chēng)為棧幀(Stack Frame)。
并且這正是都異常被拋出的時(shí)候棧追蹤是如何構(gòu)建的——這基本就是異常發(fā)生時(shí)調(diào)用棧的狀態(tài)。請(qǐng)看如下代碼:
function foo() { throw new Error("SessionStack will help you resolve crashes :)"); } function bar() { foo(); } function start() { bar(); } start();
如果這段代碼在Chrome中執(zhí)行(假設(shè)代碼是在一個(gè)叫做foo.js的文件中),接下來(lái)的棧追蹤將會(huì)產(chǎn)生:
“爆棧"——當(dāng)你達(dá)到最大調(diào)用棧的大小的時(shí)候就會(huì)發(fā)生這種情況。并且這種情況很容易產(chǎn)生,特別是你沒(méi)有對(duì)你的代碼做全面的測(cè)試的時(shí)候。請(qǐng)看下面的示例代碼:
function foo() { foo(); } foo();
當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,它一開(kāi)始調(diào)用函數(shù)”foo“。然而,這個(gè)函數(shù)遞歸調(diào)用本身并且沒(méi)有終止條件。因此在每一個(gè)執(zhí)行的步驟中,相同的函數(shù)都會(huì)一次又一次地被添加到調(diào)用棧中??雌饋?lái)就像這樣:
在某個(gè)點(diǎn),然而函數(shù)調(diào)用的數(shù)量就超過(guò)調(diào)用棧的實(shí)際尺寸,那么瀏覽器就決定采取行動(dòng),拋出一個(gè)錯(cuò)誤,看起來(lái)是這個(gè)樣子的:
在單線程環(huán)境中運(yùn)行代碼可能相當(dāng)容易因?yàn)槟悴恍枰幚矶嗑€程環(huán)境中復(fù)雜的情形——比如,死鎖。
但是在單線程環(huán)境中也可能遇到種種限制。因?yàn)镴avaScript具有一個(gè)多帶帶的調(diào)用棧,當(dāng)事情變得緩慢的時(shí)候到底發(fā)生了什么?
并發(fā)以及事件循環(huán)當(dāng)你的函數(shù)調(diào)用在調(diào)用棧中花了大量的時(shí)間來(lái)進(jìn)行到底發(fā)生了什么?比如,想象一下假如你想在瀏覽器中使用JavaScript來(lái)做一些復(fù)雜的圖像轉(zhuǎn)換。
你可能會(huì)問(wèn)——為什么這也會(huì)是一個(gè)問(wèn)題?問(wèn)題是盡管調(diào)用棧具有函數(shù)來(lái)執(zhí)行,但是瀏覽器實(shí)施中不能做任何其他的事——它被阻塞了。這意味著瀏覽器不能渲染,它不能運(yùn)行其他的代碼,它就是歇菜了。如果你希望你的app能夠具有流暢的UI的時(shí)候就會(huì)產(chǎn)生問(wèn)題。
并且這不是唯一的問(wèn)題。一旦你的瀏覽器開(kāi)始處理調(diào)用棧中的大量任務(wù),他將在很長(zhǎng)時(shí)間內(nèi)都無(wú)法響應(yīng)。大多數(shù)瀏覽器通過(guò)拋出錯(cuò)誤來(lái)采取行動(dòng),詢(xún)問(wèn)你是否想中止網(wǎng)頁(yè)。
現(xiàn)在,這并不是一種最好的用戶(hù)體驗(yàn),是不是?
因此,我們?nèi)绾卧诓蛔枞鸘I并且讓瀏覽器保持響應(yīng)的情況下執(zhí)行大量的代碼?解決方案就是異步回調(diào)。
這個(gè)將會(huì)在”JavaScript是如何工作的"的第二部分進(jìn)一步解釋。
同時(shí),如果你很難在你的JavaScript重現(xiàn)并且理解問(wèn)題的時(shí)候,可以看看 SessionStack。SessionStack記錄了你的web應(yīng)用中的一切:所有的DOM變化,用戶(hù)交互,JavaScript異常,棧追蹤,失敗的網(wǎng)絡(luò)請(qǐng)求以及調(diào)試消息。
使用SessionStack,你可以重現(xiàn)你的web應(yīng)用中的問(wèn)題就像錄像一樣,并且可以看到用戶(hù)交互的一切。
現(xiàn)在有一個(gè)免費(fèi)的計(jì)劃能夠允許你可以開(kāi)始免費(fèi)試用
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/91787.html
摘要:調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們?cè)诔绦蛑械奈恢?。?dāng)從這個(gè)函數(shù)返回的時(shí)候,就會(huì)將這個(gè)函數(shù)從棧頂彈出,這就是調(diào)用棧做的事情。而且這不是唯一的問(wèn)題,一旦你的瀏覽器開(kāi)始處理調(diào)用棧中的眾多任務(wù),它可能會(huì)停止響應(yīng)相當(dāng)長(zhǎng)一段時(shí)間。 原文地址: https://blog.sessionstack.com... PS: 好久沒(méi)寫(xiě)東西了,最近一直在準(zhǔn)備寫(xiě)一個(gè)自己的博客,最后一些技術(shù)方向已經(jīng)敲定了,又可以...
摘要:調(diào)用棧是一種單線程編程語(yǔ)言,這意味著它只有一個(gè)調(diào)用堆棧。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們?cè)诔绦蛑械奈恢?。而且這不是唯一的問(wèn)題,一旦你的瀏覽器開(kāi)始處理調(diào)用棧中的眾多任務(wù),它可能會(huì)停止響應(yīng)相當(dāng)長(zhǎng)一段時(shí)間。 本文是旨在深入研究JavaScript及其實(shí)際工作原理的系列文章中的第一篇:我們認(rèn)為通過(guò)了解JavaScript的構(gòu)建塊以及它們是如何工作的,將能夠編寫(xiě)更好的代碼和應(yīng)用程序。我們還將分...
摘要:如果我們進(jìn)入一個(gè)函數(shù),我們?cè)诙褩5捻敳?。看看下面的代碼當(dāng)引擎開(kāi)始執(zhí)行此代碼時(shí),調(diào)用堆棧將為空。之后,步驟如下調(diào)用堆棧中的每個(gè)條目稱(chēng)為堆棧幀。這正是拋出異常時(shí)構(gòu)造堆棧跟蹤的方式當(dāng)異常發(fā)生時(shí),它基本上是調(diào)用堆棧的狀態(tài)。 隨著JavaScript越來(lái)越受歡迎,團(tuán)隊(duì)正在利用這個(gè)技術(shù)棧在多個(gè)層次- 前端,后端,混合應(yīng)用程序,嵌入式設(shè)備等等提供支持。 這篇文章旨在成為系列中第一個(gè)旨在深入挖掘Jav...
摘要:本章會(huì)對(duì)語(yǔ)言引擎,運(yùn)行時(shí),調(diào)用棧做一個(gè)概述。調(diào)用棧只是一個(gè)單線程的編程語(yǔ)言,這意味著它只有一個(gè)調(diào)用棧。查看如下代碼當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,調(diào)用棧會(huì)被清空。之后,產(chǎn)生如下步驟調(diào)用棧中的每個(gè)入口被稱(chēng)為堆棧結(jié)構(gòu)。 原文請(qǐng)查閱這里,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原...
摘要:本章會(huì)對(duì)語(yǔ)言引擎,運(yùn)行時(shí),調(diào)用棧做一個(gè)概述。調(diào)用棧只是一個(gè)單線程的編程語(yǔ)言,這意味著它只有一個(gè)調(diào)用棧。查看如下代碼當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,調(diào)用棧會(huì)被清空。之后,產(chǎn)生如下步驟調(diào)用棧中的每個(gè)入口被稱(chēng)為堆棧結(jié)構(gòu)。 原文請(qǐng)查閱這里,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原...
閱讀 4063·2021-11-16 11:50
閱讀 999·2021-11-11 16:55
閱讀 3744·2021-10-26 09:51
閱讀 933·2021-09-22 15:03
閱讀 3566·2019-08-30 15:54
閱讀 3362·2019-08-30 15:54
閱讀 2548·2019-08-30 14:04
閱讀 979·2019-08-30 13:53