摘要:調用棧是一種單線程編程語言,這意味著它只有一個調用棧。這就是調用棧的功能。簡單代碼示例當引擎執行這段代碼時,調用棧為空,之后運行如下每個叫做堆棧幀。調用棧就是通過堆棧幀來追蹤異常,堆棧幀基本就是調用棧出現異常時候的狀態。
概述
幾乎每個人都已經聽說過V8引擎這個概念,而且大多人都知道JavaScript是單線程的,并且使用回調隊列。
這篇文章中,我們將詳細介紹這些概念,并解釋JavaScript實際運行的原理。通過了解這些詳細信息,將能夠編寫更好的非阻塞應用程序,以正確利用所提供的API。
JavaScript引擎最流行的JavaScript引擎莫過于Google的V8引擎,V8使用C++開發,Chrome瀏覽器和Node.js都是基于V8引擎的,簡略的示意圖:
V8引擎包含兩個主要組件:
內存堆(Memory Heap):負責內存分配
調用棧(Call Stack):代碼執行時,維護堆棧幀(Stack Frames)
幾乎所有的JavaScript開發者都使用過setTimeout這樣的API,然而這些APIs不是由V8引擎提供的。那這些APIs是哪來的呢?
盡管我們已經有了V8引擎,但實際上我們還需要更多的接口或功能。我們把那些由瀏覽器提供的接口稱為Web APIs,比如DOM,AJAX,setTimeout等等。
接下來是事件循環(event lool)和回調隊列(callback queue)。
調用棧(Call Stack)JavaScript是一種單線程編程語言,這意味著它只有一個調用棧。因此,在同一時間它只能做一件事。
調用棧是一個數據結構,它會記錄代碼執行的位置。例如我們執行進入一個函數,我們會把這個函數放在堆棧的頂部,函數執行結束返回之后,我們把這個函數從堆棧中移除。這就是調用棧的功能。
簡單代碼示例:
function multiply(x, y) { return x * y; } function printSquare(x) { var s = nultiply(x, x); console.log(s); } printSquare(5);
當引擎執行這段代碼時,調用棧為空,之后運行如下:
每個Step叫做堆棧幀(Stack Frame)。
調用棧就是通過堆棧幀來追蹤異常,堆棧幀基本就是調用棧出現異常時候的狀態。示例代碼如下:
function foo() { throw new Error("SessionStack will help you resolve crashes :)"); } function bar() { foo(); } function start() { bar(); }
假設上面代碼保存在foo.js文件,執行上面代碼在Chrome瀏覽器中,Error的堆棧信息會如下圖打印出來:
單線程執行代碼是無法充分利用CPU資源,使得運行效率低。由于JavaScript只有一個調用棧,如果運行效率變低,那應該怎么解決呢?
并發和事件循環想像一下如果調用棧里面有些函數的執行需要大量的時間,例如在瀏覽器中進行復雜的圖片轉化,情況會怎么樣,為什么會有問題?
問題就是調用棧中的函數在執行的過程中,瀏覽器是不能做其它事情的,也就是會被調用棧中的函數阻塞,此時瀏覽器不能渲染和運行其它代碼,完全被卡住了。這樣就很難實現流暢的UIs體驗。
而且另外一個問題也會由此發生,如果瀏覽器在調用棧中執行很多這樣復雜且耗時的函數時,瀏覽器也會失去響應,出現假死狀態。
這絕對不是我們要的用戶體驗。
怎么才能執行復雜且耗時的代碼,并且不會阻塞UI的渲染和導致瀏覽器假死呢?解決方案就是異步調用。異步調用會在第二篇系列文章(V8引擎和5招優化)中解釋。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94596.html
摘要:本章會對語言引擎,運行時,調用棧做一個概述。調用棧只是一個單線程的編程語言,這意味著它只有一個調用棧。查看如下代碼當引擎開始執行這段代碼的時候,調用棧會被清空。之后,產生如下步驟調用棧中的每個入口被稱為堆棧結構。 原文請查閱這里,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工作原...
摘要:本章會對語言引擎,運行時,調用棧做一個概述。調用棧只是一個單線程的編程語言,這意味著它只有一個調用棧。查看如下代碼當引擎開始執行這段代碼的時候,調用棧會被清空。之后,產生如下步驟調用棧中的每個入口被稱為堆棧結構。 原文請查閱這里,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工作原...
摘要:調用棧是一種單線程編程語言,這意味著它只有一個調用堆棧。調用棧是一種數據結構,它記錄了我們在程序中的位置。而且這不是唯一的問題,一旦你的瀏覽器開始處理調用棧中的眾多任務,它可能會停止響應相當長一段時間。 本文是旨在深入研究JavaScript及其實際工作原理的系列文章中的第一篇:我們認為通過了解JavaScript的構建塊以及它們是如何工作的,將能夠編寫更好的代碼和應用程序。我們還將分...
摘要:什么是中的調用棧調用棧就像是程序當前執行的日志。當函數執行結束時,將從調用棧中出去。了解全局和局部執行上下文是掌握作用域和閉包的關鍵。總結引擎創建執行上下文,全局存儲器和調用棧。 原文作者:Valentino 原文鏈接:https://www.valentinog.com/blog/js-execution-context-call-stack 什么是Javascript中的執行上下文...
摘要:最受歡迎的引擎是,由和使用,用于,以及使用的。引擎它們是如何工作的全局執行上下文和調用堆棧剛剛了解了引擎如何讀取變量和函數聲明,它們最終被放入了全局內存堆中。事件循環只有一個任務它檢查調用堆棧是否為空。 為了保證可讀性,本文采用意譯而非直譯。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 有沒有想過瀏覽器如何讀取和運行JS代碼? 這看起來很神奇,我們可以通過瀏覽...
閱讀 2380·2021-11-12 10:34
閱讀 1465·2019-08-29 16:15
閱讀 2678·2019-08-29 15:17
閱讀 1334·2019-08-23 17:09
閱讀 389·2019-08-23 11:37
閱讀 2451·2019-08-23 10:39
閱讀 468·2019-08-22 16:43
閱讀 3107·2019-08-22 14:53