摘要:關(guān)于異步應(yīng)該很多地方都說過,是單線程的,嚴格的說,是指引擎中負責(zé)解釋和執(zhí)行代碼的線程只有一個,除此之外,其實還有事件觸發(fā)線程請求線程等,因此,應(yīng)該說同步是單線程可能更準確些。
作者:心葉
時間:2019-03-08 09:45
先列出我的理解,然后再從具體的例子中說明:
DOM操作本身應(yīng)該是同步的(當(dāng)然,我說的是單純的DOM操作,不考慮ajax請求后渲染等)
DOM操作之后導(dǎo)致的渲染等是異步的(在DOM操作簡單的情況下,是難以察覺的)
證明存在異步DOM從操作到渲染結(jié)束,我想先用一個具體的例子來說明。
例子說明:把img標簽先追加到頁面,然后把img里面的內(nèi)容繪制到canvas上,代碼如下:
看看運行效果:
canvas上什么也沒有繪制出來,而img上面是有內(nèi)容的(也就是「這是一個例子」這段文字)。
接著,在img添加到頁面后,繪制canvas前添加一個延遲,我們修改一下第二步地方的代碼如下:
window.setTimeout(function () { document.getElementById("canvas") .getContext("2d") .drawImage(document.getElementById("img"), 0, 0); }, 100);
再次運行,查看效果:
內(nèi)容出來了。
因此,異步是存在的,只不過是在DOM操作還是渲染上就不清楚了。
證明DOM操作是同步的接著上面的例子,想證明DOM操作是同步的很簡單,依舊修改第二步的代碼如下:
window.setTimeout(function () { document.getElementById("canvas") .getContext("2d") .drawImage(document.getElementById("img22"), 0, 0); }, 100);
我們修改drawImage方法查找結(jié)點的id為一個錯誤的"img22",顯然查找不到,運行結(jié)果如下:
我們看見瀏覽器報錯了,因此,如果DOM操作是異步的,在沒有添加延遲的時候不應(yīng)該是什么都沒有繪制出來,而是應(yīng)該報錯,因此DOM是同步的,那么渲染就是異步的。
例子結(jié)束,完整代碼請見評論(方便大家閱讀放到評論去)。
關(guān)于異步應(yīng)該很多地方都說過,js是單線程的,嚴格的說,是指JS引擎中負責(zé)解釋和執(zhí)行JavaScript代碼的線程只有一個,除此之外,其實還有事件觸發(fā)線程、ajax請求線程等,因此,應(yīng)該說:同步是單線程可能更準確些。
另外,同步會阻塞異步,看一下下面的代碼:
setTimeout(function() { console.log("異步執(zhí)行了"); }, 0); while(true);
因為同步代碼while條件一直為真,你在看見『異步執(zhí)行了』前估計先看見瀏覽器頁面卡卡的。
總結(jié)DOM操作只是結(jié)點操作,而頁面最終的效果還會有render渲染樹等參與,因此,雖然DOM操作是同步的,而你期望的「DOM操作」卻不一定是同步的,包括調(diào)用外設(shè)(外設(shè)要看具體設(shè)備,有的設(shè)備會阻塞瀏覽器執(zhí)行,什么意思,就是瀏覽器的異步操作也會停止,結(jié)合這里的異步操作的理解,就可以解釋一些奇怪現(xiàn)象了)等,需要在日常開發(fā)的時候注意。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109006.html
摘要:深入理解引擎的執(zhí)行機制最近在反省,很多知識都是只會用,不理解底層的知識。在閱讀之前,請先記住兩點是單線程語言的是的執(zhí)行機制。所以,是存在異步執(zhí)行的,比如單線程是怎么實現(xiàn)異步的場景描述通過事件循環(huán),所以說,理解了機制,也就理解了的執(zhí)行機制啦。 深入理解js引擎的執(zhí)行機制 最近在反省,很多知識都是只會用,不理解底層的知識。所以在開發(fā)過程中遇到一些奇怪的比較難解決的bug,在思考的時候就會收...
摘要:還請同學(xué)跟我多多探討關(guān)于修改是異步還是同步的問題先來看代碼上述代碼的結(jié)果完全就是同步的表現(xiàn),如果是異步的話,毫無疑問,第一個下的每個內(nèi)容都應(yīng)該是,第二個也應(yīng)該是。 回 @bf 同學(xué) 本篇文章不是筆記也不是心得,而是關(guān)于一個問題的討論,問題最初出現(xiàn)于https://segmentfault.com/q/1010000005630545?_ea=903562 由于 @bf 同學(xué)不方便...
摘要:深入理解引擎的執(zhí)行機制靈魂三問為什么是單線程的為什么需要異步單線程又是如何實現(xiàn)異步的呢中的中的說說首先請牢記點是單線程語言的是的執(zhí)行機制。 深入理解JS引擎的執(zhí)行機制 1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實現(xiàn)異步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.說說setTimeout 首先,請牢記2...
摘要:的精髓在于,用維護狀態(tài)傳遞狀態(tài)的方式使得回調(diào)函數(shù)能夠及時調(diào)用,比傳遞要簡單靈活的其他方法用于指定發(fā)生錯誤時的回調(diào)函數(shù),等同于部分和的區(qū)別在發(fā)生異常,在中捕獲不到能夠捕獲異常。 ES6是個啥 ECMAScript是國際通過的標準化腳本語言JavaScript由ES,BOM,DOM組成ES是JavaScript的語言規(guī)范,同時JavaScript是ES的實現(xiàn)和擴展6就是JavaScript...
摘要:本文將解釋引起這個錯誤的內(nèi)在原因,檢測機制的內(nèi)部原理,提供導(dǎo)致這個錯誤的共同行為,并給出修復(fù)這個錯誤的解決方案。這一次過程稱為。這個程序設(shè)計為子組件拋出一個事件,而父組件監(jiān)聽這個事件,而這個事件會引起父組件屬性值發(fā)生改變。 原文鏈接:Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedE...
閱讀 1962·2021-11-24 09:39
閱讀 3542·2021-09-28 09:36
閱讀 3321·2021-09-06 15:10
閱讀 3478·2019-08-30 15:44
閱讀 1176·2019-08-30 15:43
閱讀 1826·2019-08-30 14:20
閱讀 2738·2019-08-30 12:51
閱讀 2059·2019-08-30 11:04