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