每日前端夜話,陪你聊前端。 每天晚上18:00準(zhǔn)時推送。 正文共:3098 字 9 圖 預(yù)計閱讀時間: 8 分鐘
隨著JavaScript變得越來越流行,越來越多的團隊正在利用他們?yōu)榧夹g(shù)棧中做多個級別的支持:前端、后端、混合應(yīng)用、嵌入式設(shè)備等等。 本文旨在深入挖掘JavaScript及其實際的工作方式:我們認(rèn)為通過了解JavaScript的構(gòu)建塊以及它們?nèi)绾伟l(fā)揮作用,你將能夠編寫更好的代碼和應(yīng)用。 我們還將分享自己在構(gòu)建SessionStack[https://www./]時使用的一些經(jīng)驗和規(guī)范,這是一個輕量級JavaScript應(yīng)用,必須具有強大功能和高性能才能保持競爭力。 正如GitHut stats[http:///]所示,JavaScript在GitHub中的Active Repositories和Total Pushes方面處于領(lǐng)先地位。 它也不會落后于其他語言。 如果項目越來越依賴于JavaScript,這意味著開發(fā)人員必須利用語言和其生態(tài)系統(tǒng)提供的所有內(nèi)容,更深入的了解其內(nèi)部,以便構(gòu)建出色的軟件。 事實證明,有很多開發(fā)人員每天都在使用JavaScript,卻不了解背后究竟發(fā)生了些什么。 概述幾乎每個人都已經(jīng)聽說過V8引擎這個概念,大多數(shù)人都知道JavaScript是單線程的,或者它使用的是回調(diào)隊列。 在本文中,我們將詳細(xì)介紹這些概念,并解釋JavaScript實際運行的方式。 通過了解這些詳細(xì)信息,你將能夠正確地利用其所提供的API編寫更好的、非阻塞的應(yīng)用,這些應(yīng)用正確地利用了所提供的API。 如果你對JavaScript比較陌生,那么本文將幫助你理解為什么JavaScript與其他語言相比是如此的“奇怪”。 如果你是一位經(jīng)驗豐富的JavaScript開發(fā)者,盡管你每天使用它,但仍然希望它能夠為你提供一些關(guān)于JavaScript運行時工作方式方面的新見解。 JavaScript引擎一個很流行的JavaScript引擎是Google的V8引擎。 V8引擎被用于Chrome和Node.js。 這是一個非常簡化的示意圖: 引擎包含兩個主要組件:
運行時這是幾乎所有JavaScript開發(fā)人員在瀏覽器中都使用過的API(例如“setTimeout”)。 但是引擎并不提供這些API。 那么,他們究竟來自哪里? 實際上這有點復(fù)雜。 所以盡管有了引擎,但是還需要很多東西。有一些叫做Web API的東西,它們是由瀏覽器提供的,比如DOM,AJAX,setTimeout等等。 此外還有非常受歡迎的事件循環(huán)和回調(diào)隊列。 調(diào)用棧JavaScript是一種單線程編程語言,這意味著它只有一個調(diào)用棧。 所以它一次只能做一件事。 調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了當(dāng)前程序中執(zhí)行到的基本位置。 如果我們進入一個函數(shù),會它放在棧的頂部。 如果我們從函數(shù)返回,就會將它從堆棧的頂部彈出。 這就是所有棧結(jié)構(gòu)都可以做到的。 下面我們來看一個例子吧: 當(dāng)引擎開始執(zhí)行上面的代碼時,調(diào)用堆棧將為空。 接下來的步驟如下: 調(diào)用棧中的每個條目被稱為棧幀。 這是在拋出異常時堆棧跟蹤的構(gòu)造方式 —— 當(dāng)異常發(fā)生時調(diào)用堆棧的大致狀態(tài)。 接下來看下面這段代碼: 如果在Chrome中執(zhí)行這個操作(假設(shè)此代碼位于名為foo.js的文件中),則將生成以下堆棧跟蹤: 當(dāng)達(dá)到最大調(diào)用堆棧大小時會發(fā)生“Blowing the stack”這種情況。 這種情況是很容易發(fā)生的,尤其是在你使用遞歸而沒有充分地測試你的代碼時。 看一下這段代碼: 當(dāng)引擎開始執(zhí)行此代碼時,它首先調(diào)用函數(shù)“foo”。 但是這個函數(shù)是遞歸的,并且在沒有任何終止條件的情況下開始調(diào)用自身。 因此在執(zhí)行的每個步驟中,相同的函數(shù)一次又一次地被添加到調(diào)用堆棧中。 它看起來像是這樣: 在某些時候,如果調(diào)用棧中的函數(shù)調(diào)用數(shù)量超過了它的實際大小,瀏覽器就會拋出錯誤,該錯誤看起來像這樣: 在單個線程上運行代碼非常簡單,因為你不必處理多線程環(huán)境中出現(xiàn)的復(fù)雜場景,例如死鎖。 但是跑在單個線程上也是非常受限的。 由于JavaScript只有一個調(diào)用,當(dāng)處理變慢時會發(fā)生什么? 并發(fā)和事件循環(huán)如果在調(diào)用堆棧中有需要花費大量時間才能處理的函數(shù)調(diào)用,會發(fā)生什么? 比如假設(shè)你想在瀏覽器中用JavaScript進行一些復(fù)雜的圖像轉(zhuǎn)換。 你可能會問:這也算是一個問題? 實際上雖然調(diào)用棧具有執(zhí)行功能,但瀏覽器實并沒有辦法執(zhí)行其他的操作,因為它會被阻止。 這意味著瀏覽器將無法進行渲染,也無法運行任何其他代碼,它只是被卡住了。 如果你想在自己的應(yīng)用中產(chǎn)生流暢的UI,在這里將會出現(xiàn)問題。 這并不是唯一的問題。 一旦你的瀏覽器開始在調(diào)用棧中處理如此之多的任務(wù),它可能會在相當(dāng)長的時間內(nèi)停止響應(yīng)。 大多數(shù)瀏覽器將會通過引發(fā)錯誤來解決這個問題,詢問你是否要終止網(wǎng)頁的運行。 所以這并不是最佳的用戶體驗,對嗎? 那么怎樣才能在不阻止UI,并使瀏覽器在無響應(yīng)的情況下執(zhí)行繁重的代碼呢? 解決方案是異步回調(diào)。 這一點在“如何運行JavaScript”教程的第2部分中有更詳細(xì)的解釋:“在V8引擎是怎么工作的:有關(guān)如何編寫優(yōu)化代碼的5個技巧[https://blog./how-javascript-works-inside-the-v8-engine-5-tips-on-how-to-write-optimized-code-ac089e62b12e]”。 與此同時,如果你在JavaScript應(yīng)用程序中遇到難以復(fù)制和理解的問題,可以試試SessionStack[https://www./?utm_source=medium&utm_medium=blog&utm_content=Post-1-overview-outro]。 SessionStack會記錄Web應(yīng)用中所有的內(nèi)容:所有的DOM修改、用戶交互、JavaScript異常、堆棧跟蹤、網(wǎng)絡(luò)請求失敗和調(diào)試消息。 通過SessionStack,你可以將網(wǎng)絡(luò)應(yīng)用中的問題重現(xiàn),并查看發(fā)生的所有事情。 有一個免費的工具,不需要支付任何費用。 現(xiàn)在就可以試試[https://www./solutions/developers/?utm_source=medium&utm_medium=blog&utm_content=Post-1-overview-getStarted]。 如果你覺得這篇文章對你有幫助,請點擊右下角的 “??好看” 并分享給小伙伴們↘?↘?↘????? 下面夾雜一些私貨:也許你和高薪之間只差這一張圖 2019年京程一燈課程體系上新,這是我們第一次將全部課程列表對外開放。 愿你有個好前程,愿你月薪30K。我們是認(rèn)真的 ! |
|
來自: 西北望msm66g9f > 《編程》