js setTimeout和for迴圈搭配使用時變數的問題
阿新 • • 發佈:2019-01-13
最近在寫一個定時打字的效果,需要for迴圈和setTimeout搭配使用,出現了一些問題,在網上查詢找到了問題所在。
1.setTimeout(func,time)函式執行機制
setTimeout(func,time)是在time(毫秒單位)時間後執行func函式。瀏覽器引擎按順序執行程式,遇到setTimeout會將func函式放到執行佇列中,等到主程式執行完畢之後,才開始從執行佇列(佇列中可能有多個待執行的func函式)中按照time延時時間的先後順序取出來func並執行。即使time=0,也會等主程式執行完之後,才會執行。
上例子:
執行結果可以說明問題。
2.for迴圈和setTimeout搭配使用時出現的問題
先上程式碼:
我本意是要每隔100ms列印一次i的值,每次i值應該變化,但事實卻是三次i的值都是3,也就是都是最後一次for迴圈i的值。
3.問題原因
原因是上面講的setTimeout執行機制的問題:定時函式被加入執行佇列,等主程式執行完畢時,此時再呼叫定時函式,i的值已經變為3,三次的定時函式都會共用i=3這個值。
4.解決方法
對setTimeout進行封裝,目的是要每次呼叫定時函式都有自己的私有變數值。其實就是作用域的問題,把這個問題搞清楚,就可以解決這個問題,也不止我下面的一種解決方法,但原理都是一樣。
上程式碼:
將setTimeout進行封裝,此時定時函式的變數作用域就變為f函式程式碼塊內,每次for迴圈傳給定時器的i值都會變為定時函式的私有變數值,這樣就達到了預期目的。