日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript单线程 setTimeout定时器

發布時間:2025/3/21 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript单线程 setTimeout定时器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

理解JavaScript的單線程的理念對于JavaScript學習,以及掌握其中的一些設計機制非常重要,比如回調、定時器。對于后續學習NodeJS也有很大的幫助。

通過先demo,后總結的形式,使得JavaScript的單線程更易于明白。

  • 1?var?a?=?1;??//全局變量a?
  • 2?function?test(){?
  • 3?????var?a=2;??//test中變量a?
  • 4?????setTimeout(function(){?
  • 5?????????alert(a);?//輸出test中變量a?
  • 6?????????a=3;??//修改test中變量a?
  • 7?????},3000);?
  • 8?????a=4;?//修改test中變量a?
  • 9?????setTimeout(function(){?
  • 10?????????alert(a);?//輸出test中變量a?
  • 11?????????a=5;?//修改test中變量a?
  • 12????},1000);?
  • 13????alert(a);?//輸出test中變量a?
  • 14?}?
  • 15?test();?//執行test函數?
  • 16?alert(a);?//輸出全局變量a?
  • ?
  • //運行結果:4?1?4?5??
  • /*?結果解析:先輸出test()運行結果4,然后輸出之后一行代碼的1,然后1000ms之后輸出test()中的變量a=4,最后3000ms之后輸出test()中的變量a=5?*/?
  • ?
  • /*?
  • ??運行機制:?
  • ?????1.?JavaScript是單線程,從上往下依次執行?
  • ?????2.?setTimeout異步方法存放在任務隊列中,JS主線程執行完成之后,才會取任務隊列中的任務到JS主線程中執行!?
  • ?
  • ?????->?先執行15行,然后執行16行?
  • ?????->?執行15行,調用test()方法?
  • ?????->?調用test()方法,先創建一個a變量,然后將第一個setTimeout放到setTimeout對應的線程中執行(啟動定時器timer),第8行,修改test中變量a為4,然后將第二個setTimeout添加到setTimeout對應的線程隊列中執行,執行13行,輸出test中變量a,此時為4;然后執行16行,輸出全局變量a,此時為1.?
  • ?????->?1000ms之后,將第二個setTimeout的回調函數,添加到JS任務隊列中,3000ms后將第一個setTimeout的回調函數,添加到JS任務隊列中。?
  • ?????->?JS主線程執行完成之后,會執行任務隊列的事件,第二個setTimeout優先進入任務隊列,所以優先執行,執行第10行,輸出test中的變量a,值為4,然后di11行,將test中的變量a修改為5;2000ms之后第一個setTimeout進入任務隊列,此時JS主線程棧為空,所以將其添加到JS主線程進行執行,第5行,輸出test中的變量a,此時變量的值為5,第6行修改test變量a為3.?
  • */?
  • 由此延伸以下代碼:

  • var?a?=?1;?
  • var?date?=?+new?Date();?//?小技巧:通過"+"轉換為整數?
  • function?test(){?
  • ????var?a=2;??
  • ????setTimeout(function(){?
  • ????????console.log(a+'--'+?(new?Date()-date));?
  • ????????a=3;??
  • ??????},3000);?
  • ????a=4;?
  • ????setTimeout(function(){?
  • ????????console.log(a+'--'+?(new?Date()-date));?
  • ????????a=5;?
  • ???},1000);?
  • ???console.log(a+'--'+?(new?Date()-date));?
  • }?
  • while(new?Date-date?<1000){?
  • ?
  • }?
  • test();?
  • console.log(a+'--'+?(new?Date()-date));?
  • ?
  • //執行結果:4-1000?1-1001?4-2000?5-4001?
  • 結合以下博客,整理一些重要概念:

    http://www.ruanyifeng.com/blog/2014/10/event-loop.html

    http://www.cnblogs.com/Mainz/p/3552717.html

    1、作為腳本語言,JavaScript主要功能是與用戶互動,以及操作DOM。假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為準? ->So: JavaScript就是單線程。

    2、JavaScript的任務分成兩種:同步任務和異步任務。同步任務:在主線程上排隊執行的任務,只有上一個任務執行完成了,才會執行下一個任務。異步任務:不進入主線程,而進入“任務隊列”的任務,只有“任務隊列”通知主線程,某個任務隊列可以執行了,等主線程執行完成,任務隊列才會進入主線程執行。 -> So:只要主線程空了,就會去讀“任務隊列”,這就是JavaScript的運行機制。

    3、主線程從“任務隊列”中讀取事件,這個過程是循環不斷的,所以整個事件又叫“事件循環”(Event Loop)。

    HTML5規定setTimeout()的第二個參數的最小值(最短間隔),不得低于4ms,如果低于4ms就會自動增加。在此之前,老版本瀏覽的都將最短時間設置為10ms。另外,對于那些DOM變動(尤其是設計頁面重新渲染的部分),通常不會立即執行,而是每16ms執行一次。這是使用requestAnimationFrame()的效果要好于setTimeout()。

    4、需要注意的是:setTimeout只是將事件插入“事件隊列”,必須等到前面代碼(執行棧)執行完,主線程才會去執行他指定的回調函數。如果當前代碼耗時很長,有可能要等很久,所以并沒有辦法保證,回調函數一定會在setTimeout()指定的是時間執行。

    Javascript是單線程,單線程就意味著所有任務需要排隊。然后會將所有任務分成兩類:同步任務和異步任務!同步任務:在主線程上執行的任務,只有前一個任務執行完成,才會執行后一個!異步任務:不進入主線程、而進入“任務隊列”的任務。

    Js是單線程的,但是瀏覽器是多線程的!瀏覽器是事件驅動的!

    JS運行在瀏覽器中,是單線程的,每個window一個JS線程,但是瀏覽器不是單線程。可能有多個如下線程:

    Javascript引擎線程、界面渲染線程、瀏覽器事件觸發線程、Http請求線程。

    setTimeout可以改變,js執行順序。比如:我們想要輸出Hello World,world必須在hello之后輸出,不管我們代碼的順序怎么樣都輸出同樣的效果,這個時候就可以借助setTimeout。

  • //代碼一?
  • var?date?=??+new?Date();?
  • console.log('Hello',new?Date()-date);?
  • setTimeout(function(){?
  • ?????console.log('world',new?Date()-date);?
  • },500);?
  • ?
  • //代碼二:?
  • var?date?=??+new?Date();?
  • setTimeout(function(){?
  • ?????console.log('World',new?Date()-date);?
  • },500);?
  • console.log('Hello',new?Date()-date);?
  • ?
  • //以上兩個代碼運行結果一樣,結果都是:先輸出Hello?,然后500ms之后輸出World![實際運行:501ms]?
  • 瀏覽器中定時器也是一個線程!

    Javscript是單線程的,ajax請求確實是異步的!原因是ajax請求的時候,是在瀏覽器的Http請求線程中執行的,執行之后的回調函數會放到Javascript線程中執行!

    Summary:

    Javascript是單線程的,瀏覽器是多線程的,瀏覽器的線程包括:JS引擎線程、界面渲染線程、瀏覽器事件線程、Http請求線程。不過不同的瀏覽器提供的線程是有區別的。一般JS引擎線程和界面渲染線程是互斥的,兩個線程不能同時執行,否則,就會出現界面渲染線程和JS線程修改同一個DOM樣式的矛盾問題!

    from:?http://developer.51cto.com/art/201703/533796.htm

    總結

    以上是生活随笔為你收集整理的JavaScript单线程 setTimeout定时器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。