• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. 淺談javascript中的單線程理解

        時(shí)間:2024-08-16 20:41:27 JavaScript 我要投稿
        • 相關(guān)推薦

        淺談javascript中的單線程理解

          一、JavaScript 引擎是單線程的

          可以從下面的代碼中看到,第一個(gè)用setTimeout中的代碼是死循環(huán),由于是單線程,下面的兩個(gè)定時(shí)器就沒(méi)機(jī)會(huì)執(zhí)行了。

          瀏覽器的內(nèi)核是多線程的,它們?cè)趦?nèi)核制控下相互配合以保持同步,一個(gè)瀏覽器至少實(shí)現(xiàn)3個(gè)常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發(fā)線程。

          JavaScript引擎是基于事件驅(qū)動(dòng)單線程執(zhí)行的,JS引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來(lái)然后加以處理,瀏覽器無(wú)論再什么時(shí)候都只有一個(gè)JS線程在運(yùn)行JS程序。

          GUI渲染線程負(fù)責(zé)渲染瀏覽器界面,當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時(shí),該線程就會(huì)執(zhí)行。但需要注意 GUI渲染線程與JS引擎是互斥的,當(dāng)JS引擎執(zhí)行時(shí)GUI線程會(huì)被掛起,GUI更新會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎空閑時(shí)立即被執(zhí)行。

          瀏覽器事件觸發(fā)線程,當(dāng)一個(gè)事件被觸發(fā)時(shí)該線程會(huì)把事件添加到待處理隊(duì)列的隊(duì)尾,等待JS引擎的處理。這些事件可來(lái)自JavaScript引擎當(dāng)前執(zhí)行的代碼塊如setTimeOut、也可來(lái)自瀏覽器內(nèi)核的其他線程如鼠標(biāo)點(diǎn)擊、AJAX異步請(qǐng)求等,但由于JS的單線程關(guān)系所有這些事件都得排隊(duì)等待JS引擎處理。

          由上圖可看出,瀏覽器中的JavaScript引擎是基于事件驅(qū)動(dòng)的,這里的事件可看作是瀏覽器派給它的各種任務(wù),JavaScript引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來(lái),由于單線程關(guān)系,這些任務(wù)得進(jìn)行排隊(duì),一個(gè)接著一個(gè)被引擎處理。

          t1、t2....tn表示不同的時(shí)間點(diǎn),tn下面對(duì)應(yīng)的小方塊代表該時(shí)間點(diǎn)的任務(wù)。

          t1時(shí)刻:

          1、GUI渲染線程

          2、瀏覽器事件觸發(fā)線程:

          在t1時(shí)間段內(nèi),首先是用戶(hù)點(diǎn)擊了一個(gè)鼠標(biāo)鍵,點(diǎn)擊被瀏覽器事件觸發(fā)線程捕捉后形成一個(gè)鼠標(biāo)點(diǎn)擊事件,由圖可知,對(duì)于JavaScript引擎線程來(lái)說(shuō),這事件是由其它線程異步傳到任務(wù)隊(duì)列尾的,由于引擎正在處理t1時(shí)的任務(wù),這個(gè)鼠標(biāo)點(diǎn)擊事件正在等待處理。

          3、定時(shí)觸發(fā)線程:

          這里的瀏覽器模型定時(shí)計(jì)數(shù)器并不是由JavaScript引擎計(jì)數(shù)的,因?yàn)镴avaScript引擎是單線程的,如果處于阻塞線程狀態(tài)就計(jì)不了時(shí),它必須依賴(lài)外部來(lái)計(jì)時(shí)并觸發(fā)定時(shí),所以隊(duì)列中的定時(shí)事件是異步事件。

          4、在這t1的時(shí)間段內(nèi),繼鼠標(biāo)點(diǎn)擊事件觸發(fā)后,先前已設(shè)置的setTimeout定時(shí)也到達(dá)了,此刻對(duì)JavaScript引擎來(lái)說(shuō),定時(shí)觸發(fā)線程產(chǎn)生了一個(gè)異步定時(shí)事件并放到任務(wù)隊(duì)列中,該事件被排到點(diǎn)擊事件回調(diào)之后,等待處理。同理,還是在t1時(shí)間段內(nèi),接下來(lái)某個(gè)setInterval定時(shí)器也被添加了,由于是間隔定時(shí),在t1段內(nèi)連續(xù)被觸發(fā)了兩次,這兩個(gè)事件被排到隊(duì)尾等待處理。

          5、ajax異步請(qǐng)求:

          瀏覽器新開(kāi)一個(gè)http線程請(qǐng)求,當(dāng)請(qǐng)求的狀態(tài)變更時(shí),如果先前已設(shè)置回調(diào),這異步線程就產(chǎn)生狀態(tài)變更事件放到JavaScript引擎的處理隊(duì)列中等待處理。

          二、任務(wù)的執(zhí)行順序不同,顯示結(jié)果也不同

          1)未使用setTimeout函數(shù)

          在網(wǎng)上找到的一段代碼實(shí)例,這里用來(lái)演示一下。

          do something

          我在firefox中執(zhí)行了上面的代碼。計(jì)劃是點(diǎn)擊“do something”按鈕,然后顯示“doing...please wait...”,接著執(zhí)行sleep,最后顯示“done”。

          但是結(jié)果是點(diǎn)擊后,瀏覽器卡住3秒左右,最后直接顯示done。

          分析下看出,在做status.innerHTML設(shè)置的時(shí)候,是需要執(zhí)行GUI渲染線程的,但是現(xiàn)在還在執(zhí)行JavaScript引擎線程,而JavaScript引擎線程與GUI渲染線程是互斥的,所以就最后顯示了done。

          2)使用了setTimeout函數(shù)

          do something timer

          在“doing...please wait...”后面加了個(gè)setTimeout,延時(shí)執(zhí)行,給了瀏覽器渲染的時(shí)間,這個(gè)時(shí)候會(huì)顯示出“doing...please wait...”的字樣,然后執(zhí)行sleep函數(shù),最后顯示“done”。

          后面有網(wǎng)友發(fā)現(xiàn)在firefox中不起作用,的確有這個(gè)問(wèn)題,后面我修改了一下代碼,將局部變量的聲明,onclick的綁定放到了window.onload事件中,等頁(yè)面結(jié)構(gòu)加載完成后,我再做腳本操作。

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

        【淺談javascript中的單線程理解】相關(guān)文章:

        對(duì)javascript的理解03-29

        javascript面向?qū)ο笾械膶?duì)象怎么理解03-30

        有關(guān)深入理解JavaScript中的并行處理的介紹03-30

        理解JavaScript原型鏈教程03-30

        淺談如何深入學(xué)習(xí)Javascript中的this關(guān)鍵字04-02

        javascript的閉包概念怎么理解03-29

        在Java中執(zhí)行JavaScript代碼04-01

        Javascript中typeof 用法歸納04-01

        JavaScript中的with關(guān)鍵字03-25

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 中文字幕欧美精品制服丝袜 | 先锋影音视频一区视频二区 | 最新看片国产精品免费在线 | 亚洲乱码一区二区三区在线观看 | 一本久久久综合精品视频 | 一本久久α久久免费精 |

            淺談javascript中的單線程理解

              一、JavaScript 引擎是單線程的

              可以從下面的代碼中看到,第一個(gè)用setTimeout中的代碼是死循環(huán),由于是單線程,下面的兩個(gè)定時(shí)器就沒(méi)機(jī)會(huì)執(zhí)行了。

              瀏覽器的內(nèi)核是多線程的,它們?cè)趦?nèi)核制控下相互配合以保持同步,一個(gè)瀏覽器至少實(shí)現(xiàn)3個(gè)常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發(fā)線程。

              JavaScript引擎是基于事件驅(qū)動(dòng)單線程執(zhí)行的,JS引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來(lái)然后加以處理,瀏覽器無(wú)論再什么時(shí)候都只有一個(gè)JS線程在運(yùn)行JS程序。

              GUI渲染線程負(fù)責(zé)渲染瀏覽器界面,當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時(shí),該線程就會(huì)執(zhí)行。但需要注意 GUI渲染線程與JS引擎是互斥的,當(dāng)JS引擎執(zhí)行時(shí)GUI線程會(huì)被掛起,GUI更新會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎空閑時(shí)立即被執(zhí)行。

              瀏覽器事件觸發(fā)線程,當(dāng)一個(gè)事件被觸發(fā)時(shí)該線程會(huì)把事件添加到待處理隊(duì)列的隊(duì)尾,等待JS引擎的處理。這些事件可來(lái)自JavaScript引擎當(dāng)前執(zhí)行的代碼塊如setTimeOut、也可來(lái)自瀏覽器內(nèi)核的其他線程如鼠標(biāo)點(diǎn)擊、AJAX異步請(qǐng)求等,但由于JS的單線程關(guān)系所有這些事件都得排隊(duì)等待JS引擎處理。

              由上圖可看出,瀏覽器中的JavaScript引擎是基于事件驅(qū)動(dòng)的,這里的事件可看作是瀏覽器派給它的各種任務(wù),JavaScript引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來(lái),由于單線程關(guān)系,這些任務(wù)得進(jìn)行排隊(duì),一個(gè)接著一個(gè)被引擎處理。

              t1、t2....tn表示不同的時(shí)間點(diǎn),tn下面對(duì)應(yīng)的小方塊代表該時(shí)間點(diǎn)的任務(wù)。

              t1時(shí)刻:

              1、GUI渲染線程

              2、瀏覽器事件觸發(fā)線程:

              在t1時(shí)間段內(nèi),首先是用戶(hù)點(diǎn)擊了一個(gè)鼠標(biāo)鍵,點(diǎn)擊被瀏覽器事件觸發(fā)線程捕捉后形成一個(gè)鼠標(biāo)點(diǎn)擊事件,由圖可知,對(duì)于JavaScript引擎線程來(lái)說(shuō),這事件是由其它線程異步傳到任務(wù)隊(duì)列尾的,由于引擎正在處理t1時(shí)的任務(wù),這個(gè)鼠標(biāo)點(diǎn)擊事件正在等待處理。

              3、定時(shí)觸發(fā)線程:

              這里的瀏覽器模型定時(shí)計(jì)數(shù)器并不是由JavaScript引擎計(jì)數(shù)的,因?yàn)镴avaScript引擎是單線程的,如果處于阻塞線程狀態(tài)就計(jì)不了時(shí),它必須依賴(lài)外部來(lái)計(jì)時(shí)并觸發(fā)定時(shí),所以隊(duì)列中的定時(shí)事件是異步事件。

              4、在這t1的時(shí)間段內(nèi),繼鼠標(biāo)點(diǎn)擊事件觸發(fā)后,先前已設(shè)置的setTimeout定時(shí)也到達(dá)了,此刻對(duì)JavaScript引擎來(lái)說(shuō),定時(shí)觸發(fā)線程產(chǎn)生了一個(gè)異步定時(shí)事件并放到任務(wù)隊(duì)列中,該事件被排到點(diǎn)擊事件回調(diào)之后,等待處理。同理,還是在t1時(shí)間段內(nèi),接下來(lái)某個(gè)setInterval定時(shí)器也被添加了,由于是間隔定時(shí),在t1段內(nèi)連續(xù)被觸發(fā)了兩次,這兩個(gè)事件被排到隊(duì)尾等待處理。

              5、ajax異步請(qǐng)求:

              瀏覽器新開(kāi)一個(gè)http線程請(qǐng)求,當(dāng)請(qǐng)求的狀態(tài)變更時(shí),如果先前已設(shè)置回調(diào),這異步線程就產(chǎn)生狀態(tài)變更事件放到JavaScript引擎的處理隊(duì)列中等待處理。

              二、任務(wù)的執(zhí)行順序不同,顯示結(jié)果也不同

              1)未使用setTimeout函數(shù)

              在網(wǎng)上找到的一段代碼實(shí)例,這里用來(lái)演示一下。

              do something

              我在firefox中執(zhí)行了上面的代碼。計(jì)劃是點(diǎn)擊“do something”按鈕,然后顯示“doing...please wait...”,接著執(zhí)行sleep,最后顯示“done”。

              但是結(jié)果是點(diǎn)擊后,瀏覽器卡住3秒左右,最后直接顯示done。

              分析下看出,在做status.innerHTML設(shè)置的時(shí)候,是需要執(zhí)行GUI渲染線程的,但是現(xiàn)在還在執(zhí)行JavaScript引擎線程,而JavaScript引擎線程與GUI渲染線程是互斥的,所以就最后顯示了done。

              2)使用了setTimeout函數(shù)

              do something timer

              在“doing...please wait...”后面加了個(gè)setTimeout,延時(shí)執(zhí)行,給了瀏覽器渲染的時(shí)間,這個(gè)時(shí)候會(huì)顯示出“doing...please wait...”的字樣,然后執(zhí)行sleep函數(shù),最后顯示“done”。

              后面有網(wǎng)友發(fā)現(xiàn)在firefox中不起作用,的確有這個(gè)問(wèn)題,后面我修改了一下代碼,將局部變量的聲明,onclick的綁定放到了window.onload事件中,等頁(yè)面結(jié)構(gòu)加載完成后,我再做腳本操作。