亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

如何通過setTimeout理解JS運行機制詳解

2024-05-06 16:49:21
字體:
來源:轉載
供稿:網友

setTimeout()函數:用來指定某個函數或某段代碼在多少毫秒之后執行。它返回一個整數,表示定時器timer的編號,可以用來取消該定時器。

例子

console.log(1);setTimeout(function () { console.log(2);}, 0);console.log(3);

問:最后的打印順序是什么?(如果不了解js的運行機制就會答錯)

正確答案:1 3 2

解析:無論setTimeout的執行時間是0還是1000,結果都是先輸出3后輸出2,這就是面試官常??疾榈膉s運行機制的問題,接下來我們要引入一個概念,JavaScript 是單線程的。

二、 JavaScript 單線程

JavasScript引擎是基于事件驅動和單線程執行的,JS引擎一直等待著任務隊列中任務的到來,然后加以處理,瀏覽器無論什么時候都只有一個JS線程在運行程序,即主線程。

通俗的說:JS在同一時間內只能做一件事,這也常被稱為 “阻塞式執行”。

任務隊列

那么單線程的JavasScript是怎么實現“非阻塞執行”呢?

答:異步容易實現非阻塞,所以在JavaScript中對于耗時的操作或者時間不確定的操作,使用異步就成了必然的選擇。
諸如事件點擊觸發回調函數、ajax通信、計時器這種異步處理是如何實現的呢?

答:任務隊列

所有任務可以分成兩種,一種是同步任務(synchronous),另一種是異步任務(asynchronous)。

任務隊列:一個先進先出的隊列,它里面存放著各種事件和任務。

同步任務

同步任務:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行后一個任務。

  • 輸出
  • 如:console.log()
  • 變量的聲明
  • 同步函數:如果在函數返回的時候,調用者就能夠拿到預期的返回值或者看到預期的效果,那么這個函數就是同步的。

異步任務

  • setTimeout和setInterval
  • DOM事件
  • Promise
  • process.nextTick
  • fs.readFile
  • http.get
  • 異步函數:如果在函數返回的時候,調用者還不能夠得到預期結果,而是需要在將來通過一定的手段得到,那么這個函數就是異步的。

除此之外,任務隊列又分為macro-task(宏任務)與micro-task(微任務),在ES5標準中,它們被分別稱為task與job。

宏任務

  1. I/O
  2. setTimeout
  3. setInterval
  4. setImmdiate
  5. requestAnimationFrame

微任務

  1. process.nextTick
  2. Promise
  3. Promise.then
  4. MutationObserver

宏任務和微任務的執行順序

一次事件循環中,先執行宏任務隊列里的一個任務,再把微任務隊列里的所有任務執行完畢,再去宏任務隊列取下一個宏任務執行。

注:在當前的微任務沒有執行完成時,是不會執行下一個宏任務的。

三、setTimeout運行機制

setTimeout 和 setInterval的運行機制是將指定的代碼移出本次執行,等到下一輪 Event Loop 時,再檢查是否到了指定時間。如果到了,就執行對應的代碼;如果不到,就等到再下一輪 Event Loop 時重新判斷。

這意味著,setTimeout指定的代碼,必須等到本次執行的所有同步代碼都執行完,才會執行。

優先關系:異步任務要掛起,先執行同步任務,同步任務執行完畢才會響應異步任務。

四、進階

console.log('A');setTimeout(function () { console.log('B');}, 0);while (1) {}

大家再猜一下這段程序輸出的結果會是什么?

答:A

注:建議先注釋掉while循環代碼塊的代碼,執行后強制刪除進程,不然會造成“假死”。

同步隊列輸出A之后,陷入while(true){}的死循環中,異步任務不會被執行。

類似的,有時addEventListener()方法監聽點擊事件click,用戶點了某個按鈕會卡死,就是因為當前JS正在處理同步隊列,無法將click觸發事件放入執行棧,不會執行,出現“假死”。

五、定時獲取接口更新數據

for (var i = 0; i < 4; i++) { setTimeout(function () { console.log(i); }, 1000);}

輸出結果為,隔1s后一起輸出:4 4 4 4

for循環是一個同步任務,為什么連續輸出四個4?

答:因為有隊列插入的時間,即使執行時間從1000改成0,還是輸出四個4。

那么這個問題是如何產生和解決的呢?請接著閱讀

異步隊列執行的時間

執行到異步任務的時候,會直接放到異步隊列中嗎?

答案是不一定的。

因為瀏覽器有個定時器(timer)模塊,定時器到了執行時間才會把異步任務放到異步隊列。
for循環體執行的過程中并沒有把setTimeout放到異步隊列中,只是交給定時器模塊了。4個循環體執行速度非常快(不到1毫秒)。定時器到了設置的時間才會把setTimeout語句放到異步隊列中。

即使setTimeout設置的執行時間為0毫秒,也按4毫秒算。

這就解釋了上題為什么會連續輸出四個4的原因。

HTML5 標準規定了setTimeout()的第二個參數的最小值,即最短間隔,不得低于4毫秒。如果低于這個值,就會自動增加。在此之前,老版本的瀏覽器都將最短間隔設為10毫秒。

利用閉包實現 setTimeout 間歇調用

for (let i = 0; i < 4; i++) { (function (j) { setTimeout(function () {  console.log(j); }, 1000 * i) })(i);}

執行后,會隔1s輸出一個值,分別是:0 1 2 3

  • 此方法巧妙利用IIFE聲明即執行的函數表達式來解決閉包造成的問題。
  • 將var改為let,使用了ES6語法。

這里也可以用setInterval()方法來實現間歇調用。

詳見:setTimeout和setInterval的區別

利用JS中基本類型的參數傳遞是按值傳遞的特征實現

var output = function (i) { setTimeout(function () { console.log(i); }, 1000 * i)}for (let i = 0; i < 4; i++) { output(i);}

執行后,會隔1s輸出一個值,分別是:0 1 2 3

實現原理:傳過去的i值被復制了。

基于Promise的解決方案

const tasks = [];const output = (i) => new Promise((resolve) => { setTimeout(() => { console.log(i); resolve(); }, 1000 * i);});//生成全部的異步操作for (var i = 0; i < 5; i++) { tasks.push(output(i));}//同步操作完成后,輸出最后的iPromise.all(tasks).then(() => { setTimeout(() => { console.log(i); }, 1000)})

執行后,會隔1s輸出一個值,分別是:0 1 2 3 4 5

優點:提高了代碼的可讀性。

注意:如果沒有處理Promise的reject,會導致錯誤被丟進黑洞。

使用ES7中的async await特性的解決方案(推薦)

const sleep = (timeountMS) => new Promise((resolve) => { setTimeout(resolve, timeountMS);});(async () => { //聲明即執行的async for (var i = 0; i < 5; i++) { await sleep(1000); console.log(i); } await sleep(1000); console.log(i);})();

執行后,會隔1s輸出一個值,分別是:0 1 2 3 4 5

六、事件循環 Event Loop

setTimeout,JS,運行機制

主線程從任務隊列中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為Event Loop。

有時候 setTimeout明明寫的延時3秒,實際卻5,6秒才執行函數,這又是因為什么?

答:setTimeout 并不能保證執行的時間,是否及時執行取決于 JavaScript 線程是擁擠還是空閑。

瀏覽器的JS引擎遇到setTimeout,拿走之后不會立即放入異步隊列,同步任務執行之后,timer模塊會到設置時間之后放到異步隊列中。js引擎發現同步隊列中沒有要執行的東西了,即運行??樟司蛷漠惒疥犃兄凶x取,然后放到運行棧中執行。所以setTimeout可能會多了等待線程的時間。

這時setTimeout函數體就變成了運行棧中的執行任務,運行??樟?,再監聽異步隊列中有沒有要執行的任務,如果有就繼續執行,如此循環,就叫Event Loop。

七、總結

JavaScript通過事件循環和瀏覽器各線程協調共同實現異步。同步可以保證順序一致,但是容易導致阻塞;異步可以解決阻塞問題,但是會改變順序性。

知識點梳理:

  • 理解JS的單線程的概念:一段時間內做一件事
  • 理解任務隊列:同步任務、異步任務
  • 理解 Event Loop
  • 理解哪些語句會放入異步任務隊列
  • 理解語句放入異步任務隊列的時機

最后,希望大家閱后有所收獲。
注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品亚洲美女av网站| 日韩动漫免费观看电视剧高清| 亚洲精品电影网| 久久久精品国产网站| 国产99久久久欧美黑人| 欧美大片在线看免费观看| 精品国产乱码久久久久久天美| 国产精品免费在线免费| 日韩成人网免费视频| 国产精品久久99久久| 国模精品视频一区二区| 国产在线高清精品| 亚洲视频第一页| 成人国产精品色哟哟| 亚洲国产精品国自产拍av秋霞| 久久久久久久电影一区| 亚洲无亚洲人成网站77777| 欧美精品精品精品精品免费| 成人免费大片黄在线播放| 欧美尺度大的性做爰视频| 91久久久久久国产精品| 国产91免费观看| 国产精品午夜国产小视频| 亚洲欧美一区二区精品久久久| 久久久久免费精品国产| 国产精品日韩专区| 亚洲欧美国内爽妇网| 成人中心免费视频| 成人激情视频网| 一道本无吗dⅴd在线播放一区| 国产精品丝袜视频| 久久国产精品久久久| 97国产一区二区精品久久呦| 亚洲最大成人在线| 国产精品久久久久久久久久ktv| 成人性生交大片免费观看嘿嘿视频| 欧美激情视频三区| 亚洲全黄一级网站| 最近日韩中文字幕中文| 日韩一区av在线| 欧美高清视频免费观看| 国产在线拍揄自揄视频不卡99| 欧美精品18videosex性欧美| 久久久免费在线观看| 精品香蕉在线观看视频一| 午夜精品一区二区三区在线播放| 国产在线精品成人一区二区三区| 亚洲肉体裸体xxxx137| 国产视频福利一区| 中文字幕久精品免费视频| 久久成人免费视频| 国产精品永久免费| 日韩小视频网址| 欧美性色视频在线| 国产一区二区三区免费视频| 成人午夜在线视频一区| 日韩三级成人av网| 久久人91精品久久久久久不卡| 97超碰蝌蚪网人人做人人爽| 国产精品国产三级国产aⅴ浪潮| 中文字幕亚洲欧美在线| 日韩在线观看成人| 精品国产91久久久久久| 欧美老肥婆性猛交视频| 亚洲第五色综合网| 日本久久久久久| 欧美午夜性色大片在线观看| 神马久久久久久| 国产日韩欧美在线看| 国产美女精品视频| 国产视频在线一区二区| 日韩欧美极品在线观看| 69av视频在线播放| 国产精品吊钟奶在线| 欧美日韩美女视频| 欧美成人在线免费视频| 国产精品欧美日韩一区二区| 91精品国产91久久久久久不卡| 国产精品亚洲精品| 国产91免费观看| 国产精品久久久久久久av电影| 日韩av大片在线| 久久久久久国产三级电影| 欧美—级高清免费播放| 国产精品视频地址| 日韩中文在线中文网在线观看| 九九九热精品免费视频观看网站| 国内精品久久久久伊人av| 久久天天躁夜夜躁狠狠躁2022| 亚洲欧美在线x视频| 国产精品电影在线观看| 国产精品一二三在线| 国产日韩在线看| 亚洲一区二区少妇| 伊人久久综合97精品| 国产精品人成电影| 亚洲欧美精品一区| 午夜精品国产精品大乳美女| 欧美与黑人午夜性猛交久久久| 国产日韩中文在线| 97热在线精品视频在线观看| 精品小视频在线| 成人免费视频xnxx.com| 91av福利视频| 欧美日本国产在线| 日韩欧美国产成人| 91理论片午午论夜理片久久| 国产一区二区精品丝袜| 亚洲国产天堂网精品网站| 国产成人亚洲综合青青| 992tv成人免费影院| 国产精品网红福利| 亚洲女在线观看| 色老头一区二区三区在线观看| 亚洲精品久久久一区二区三区| 亚洲日韩欧美视频一区| 国产精品久久久久影院日本| 欧美视频在线看| 欧美激情网站在线观看| 国产欧美精品xxxx另类| 日韩最新av在线| 久久亚洲精品中文字幕冲田杏梨| 久久五月天色综合| 91伊人影院在线播放| 国产精品久久久久久久app| 91精品在线一区| 色偷偷av亚洲男人的天堂| 欧美第一淫aaasss性| 亚洲精品www久久久久久广东| 亚洲九九九在线观看| 亚洲一区二区三区乱码aⅴ| 欧美日韩国产精品一区二区三区四区| 色婷婷综合久久久久中文字幕1| 51久久精品夜色国产麻豆| 国产精品视频白浆免费视频| 午夜精品一区二区三区在线视| 91精品国产高清自在线看超| 欧美一级高清免费播放| 国产美女久久精品| 播播国产欧美激情| 亚洲在线免费观看| 久久人91精品久久久久久不卡| 国产精品美女久久久免费| 欧美极品少妇与黑人| 91亚洲精品久久久久久久久久久久| 亚洲精品女av网站| 综合国产在线视频| 欧美韩国理论所午夜片917电影| 国产日韩欧美另类| 亚洲日本中文字幕免费在线不卡| 欧美激情在线播放| 精品久久在线播放| 91午夜在线播放| 精品久久香蕉国产线看观看gif| 亚洲女人被黑人巨大进入| 日韩欧美在线观看| 国产日韩av高清| 欧美在线性视频| 日韩在线视频导航| 亚洲女同精品视频| 国产极品精品在线观看| 夜夜嗨av色综合久久久综合网| 亚洲电影av在线| 亚洲性av在线|