js setTimeout運行機制

在開始以前先看個面試例子面試

爲何會是0 1 2 2,而不是 0 0 1 1瀏覽器

再來看個例子閉包

 

輸出結果是4個undefined,爲什麼不是1,2,3,4?異步

這是爲何呢,這是由於setTimeout是異步的,運行機制是指定的代碼,必須等到本次執行的全部同步代碼都執行完,纔會執行。優先關係:異步任務要掛起,先執行同步任務,同步任務執行完畢纔會響應異步任務。
函數

這裏解釋下異步執行過程,瀏覽器有個定時器(timer)模塊,定時器到了執行時間纔會把異步任務放到異步隊列,for循環體執行的過程當中並無把setTimeout放到異步隊列中,只是交給定時器模塊了。4個循環體執行速度很是快(不到1毫秒)。定時器(即便設置了0默認也是4毫秒)到了設置的時間纔會把setTimeout語句放到異步隊列中。spa

看張圖:blog

先來講說第一個例子:for循環結束時候此時j = 2,瀏覽器定時器模塊中的setTimeout交給了任務隊列後輸出,因此就有了0=》1=》2=》2token

再來講說第二個例子:也是一樣的道理,messages執行了四次,而後for循環結束,此時i=4,由於messages[4]沒有值爲undefined,最大爲3,全部是4個undefined隊列

最後說說例二解決方法作用域

方法一:

使用let,不要用var,由於let是有做用域的,因此settimeout的i值指向的是每一個循環體中的i值,每次循環的值都是不同的,打印出來的是最終輸出1,2,3,4

方法二(閉包):

這個就很好理解了,由於每一個i的值都會傳入function中,settimeout中的i做用域在這個閉包中,每次指向的是閉包中的i,因此打印出來的值1,2,3,4

總結:setTimeout是異步函數,異步任務要掛起,先執行同步任務,同步任務執行完畢纔會響應異步任務

相關文章
相關標籤/搜索