摘要:調(diào)用棧是一種單線程編程語言,這意味著它只有一個調(diào)用堆棧。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們在程序中的位置。而且這不是唯一的問題,一旦你的瀏覽器開始處理調(diào)用棧中的眾多任務(wù),它可能會停止響應(yīng)相當長一段時間。
本文是旨在深入研究JavaScript及其實際工作原理的系列文章中的第一篇:我們認為通過了解JavaScript的構(gòu)建塊以及它們是如何工作的,將能夠編寫更好的代碼和應(yīng)用程序。我們還將分享構(gòu)建 SeStHealsStad 時使用的一些經(jīng)驗法則,這是一個輕量級的 JavaScript 應(yīng)用程序,必須保持健壯和高性能以保持競爭力。
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
如 GitHut 統(tǒng)計 數(shù)據(jù)所示,在GitHub中的活動存儲庫和總推送方面,JavaScript處于頂部。它也不落后于其他類別。
如果項目越來越依賴于 JavaScript,這意味著開發(fā)人員必須利用語言和生態(tài)系統(tǒng)提供的所有內(nèi)容,對內(nèi)部進行更深入的了解,以便構(gòu)建出色的軟件。
事實證明,有很多開發(fā)人員每天都在使用JavaScript,但卻不知道背后發(fā)生了什么。
概述幾乎每個人都已經(jīng)聽說過 V8 引擎,大多數(shù)人都知道 JavaScript 是單線程的,或者它使用的是回調(diào)隊列。
在本文中,我們將詳細介紹這些概念,并解釋 JavaScrip 實際如何運行。通過了解這些細節(jié),你將能夠適當?shù)乩盟峁┑?API 來編寫更好的、非阻塞的應(yīng)用程序。
如果您對JavaScript還比較陌生,那么本文將幫助您理解為什么JavaScript與其他語言相比如此“怪異”。
如果你是一個有經(jīng)驗的JavaScript開發(fā)人員,希望它能讓您對每天使用的JavaScript運行時的實際工作方式有一些新的見解。
JavaScript引擎JavaScript引擎的一個流行示例是Google的V8引擎。例如,在Chrome和Node.js中使用V8引擎,下面是一個非常簡化的視圖:
V8引擎由兩個主要部件組成:
emory Heap(內(nèi)存堆)?—?內(nèi)存分配地址的地方
Call Stack(調(diào)用堆棧) — 代碼執(zhí)行的地方
Runtime(運行時)有些瀏覽器的 API 經(jīng)常被使用到(比如說:setTimeout),但是,這些 API 卻不是引擎提供的。那么,他們是從哪兒來的呢?事實上這里面實際情況有點復(fù)雜。
所以說我們還有很多引擎之外的 API,我們把這些稱為瀏覽器提供 API 稱為 Web API,比如說 DOM、AJAX、setTimeout等等。
然后我們還擁有如此流行的事件循環(huán)和回調(diào)隊列。
調(diào)用棧JavaScript是一種單線程編程語言,這意味著它只有一個調(diào)用堆棧。因此,它一次只能做一件事。
調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們在程序中的位置。如果我們運行到一個函數(shù),它就會將其放置到棧頂,當從這個函數(shù)返回的時候,就會將這個函數(shù)從棧頂彈出,這就是調(diào)用棧做的事情。
來個栗子:
當程序開始執(zhí)行的時候,調(diào)用棧是空的,然后,步驟如下:
每一個進入調(diào)用棧的都稱為調(diào)用幀。
這能清楚的知道當異常發(fā)生的時候堆棧追蹤是怎么被構(gòu)造的,堆棧的狀態(tài)是如何的,讓我們看一下下面的代碼:
如果這發(fā)生在 Chrome 里(假設(shè)這段代碼實在一個名為 foo.js 的文件中),那么將會生成以下的堆棧追蹤:
"堆棧溢出",當你達到調(diào)用棧最大的大小的時候就會發(fā)生這種情況,而且這相當容易發(fā)生,特別是在你寫遞歸的時候卻沒有全方位的測試它。我們來看看下面的代碼:
當引擎開始執(zhí)行這段代碼時,它首先調(diào)用函數(shù)“foo”。然而,這個函數(shù)是遞歸的,并且在沒有任何終止條件的情況下開始調(diào)用自己。因此,在執(zhí)行的每一步中,相同的函數(shù)都會被一次又一次地添加到調(diào)用堆棧中,如下所示:
然而,在某些時候,調(diào)用堆棧中的函數(shù)調(diào)用數(shù)量超過了調(diào)用堆棧的實際大小,瀏覽器決定采取行動,拋出一個錯誤,它可能是這樣的:
在單個線程上運行代碼很容易,因為你不必處理在多線程環(huán)境中出現(xiàn)的復(fù)雜場景——例如死鎖。
但是在一個線程上運行也非常有限制,由于 JavaScript 只有一個調(diào)用堆棧,當某段代碼運行變慢時會發(fā)生什么?
當調(diào)用堆棧中的函數(shù)調(diào)用需要花費大量時間來處理時會發(fā)生什么情況? 例如,假設(shè)你希望在瀏覽器中使用JavaScript進行一些復(fù)雜的圖像轉(zhuǎn)換。
你可能會問-為什么這是一個問題?問題是,當調(diào)用堆棧有函數(shù)要執(zhí)行時,瀏覽器實際上不能做任何其他事情——它被阻塞了,這意味著瀏覽器不能呈現(xiàn),它不能運行任何其他代碼,它只是卡住了,如果你想在應(yīng)用中使用流暢的頁面效果,這就會產(chǎn)生問題。
而且這不是唯一的問題,一旦你的瀏覽器開始處理調(diào)用棧中的眾多任務(wù),它可能會停止響應(yīng)相當長一段時間。大多數(shù)瀏覽器都會這么做,報一個錯誤,詢問你是否想終止 web 頁面。
這并不是最好的用戶體驗,不是嗎?
那么,我們怎樣才能在不阻塞UI和不使瀏覽器失去響應(yīng)的情況下執(zhí)行大量代碼呢?解決方案是異步回調(diào)。
這個在下一篇說明,我盡快把原作者的內(nèi)容整理好!
代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行l(wèi)og 調(diào)試,這邊順便給大家推薦一個好用的BUG監(jiān)控工具 Fundebug。
原文:https://blog.sessionstack.com...
你的點贊是我持續(xù)分享好東西的動力,歡迎點贊!
交流干貨系列文章匯總?cè)缦拢X得不錯點個Star,歡迎 加群 互相學習。
https://github.com/qq44924588...
我是小智,公眾號「大遷世界」作者,對前端技術(shù)保持學習愛好者。我會經(jīng)常分享自己所學所看的干貨,在進階的路上,共勉!
關(guān)注公眾號,后臺回復(fù)福利,即可看到福利,你懂的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/99968.html
摘要:如果我們進入一個函數(shù),我們在堆棧的頂部。看看下面的代碼當引擎開始執(zhí)行此代碼時,調(diào)用堆棧將為空。之后,步驟如下調(diào)用堆棧中的每個條目稱為堆棧幀。這正是拋出異常時構(gòu)造堆棧跟蹤的方式當異常發(fā)生時,它基本上是調(diào)用堆棧的狀態(tài)。 隨著JavaScript越來越受歡迎,團隊正在利用這個技術(shù)棧在多個層次- 前端,后端,混合應(yīng)用程序,嵌入式設(shè)備等等提供支持。 這篇文章旨在成為系列中第一個旨在深入挖掘Jav...
摘要:為了方便大家共同學習,整理了之前博客系列的文章,目前已整理是如何工作這個系列,可以請猛戳博客查看。以下列出該系列目錄,歡迎點個星星,我將更友動力整理理優(yōu)質(zhì)的文章,一起學習。 為了方便大家共同學習,整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作這個系列,可以請猛戳GitHub博客查看。 以下列出該系列目錄,歡迎點個星星,我將更友動力整理理優(yōu)質(zhì)的文章,一起學習。 J...
摘要:調(diào)用堆棧是存放原始數(shù)據(jù)類型的地方除了函數(shù)調(diào)用之外。上一節(jié)中聲明變量后調(diào)用堆棧的粗略表示如下。解釋改變的正確方法是更改內(nèi)存地址。在聲明時,將在調(diào)用堆棧上分配內(nèi)存地址,該值是在堆上分配的內(nèi)存地址。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 21 篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯過了前面的章節(jié),可以在這里找到它們:...
摘要:無論你使用的是解釋型語言還是編譯型語言,都有一個共同的部分將源代碼作為純文本解析為抽象語法樹的數(shù)據(jù)結(jié)構(gòu)。和抽象語法樹相對的是具體語法樹,通常稱作分析樹。這是引入字節(jié)碼緩存的原因。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 14 篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯過了前面的章節(jié),可以在這里找到它們: JavaS...
摘要:調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們在程序中的位置。當從這個函數(shù)返回的時候,就會將這個函數(shù)從棧頂彈出,這就是調(diào)用棧做的事情。而且這不是唯一的問題,一旦你的瀏覽器開始處理調(diào)用棧中的眾多任務(wù),它可能會停止響應(yīng)相當長一段時間。 原文地址: https://blog.sessionstack.com... PS: 好久沒寫東西了,最近一直在準備寫一個自己的博客,最后一些技術(shù)方向已經(jīng)敲定了,又可以...
閱讀 3159·2021-11-22 14:45
閱讀 3311·2019-08-29 13:11
閱讀 2310·2019-08-29 12:31
閱讀 928·2019-08-29 11:21
閱讀 2998·2019-08-29 11:09
閱讀 3625·2019-08-28 18:11
閱讀 1427·2019-08-26 13:58
閱讀 1280·2019-08-26 13:27