setTimeout傳參 和 執行機制

2022-08-31 00:33:14 字數 2042 閱讀 2096

settimeout還允許新增更多的引數。它們將被傳入推遲執行的函式(**函式)

上面**中,settimeout共有4個引數。最後那兩個引數,將在1000毫秒之後**函式執行時,作為**函式的引數。

settimeout和setinterval的執行機制是,將指定的**移出本次執行,等到下一輪event loop時,再檢查是否到了指定時間。如果到了,就執行對應的**;如果不到,就等到再下一輪event loop時重新判斷。這意味著,settimeout指定的**,必須等到本次執行的所有**都執行完,才會執行。

每一輪event loop時,都會將「任務佇列」中需要執行的任務,一次執行完。settimeout和setinterval都是把任務新增到「任務佇列」的尾部。因 此,它們實際上要等到當前指令碼的所有同步任務執行完,然後再等到本次event loop的「任務佇列」的所有任務執行完,才會開始執行。由於前面的任務到底需要多少時間執行完,是不確定的,所以沒有辦法保證,settimeout和 setinterval指定的任務,一定會按照預定時間執行。

執行下面代,func1和func2誰會先執行?很明顯func2先執行;

settimeout的作用是將**推遲到指定時間執行,如果指定時間為0,即settimeout(f,0),那麼會立刻執行嗎?

答案是不會。因為settimeout執行機制說過,必須要等到當前指令碼的同步任務和「任務佇列」中已有的事 件,全部處理完以後,才會執行settimeout指定的任務。也就是說,settimeout的真正作用是,在「任務佇列」的現有事件的後面再新增乙個 事件,規定在指定時間執行某段**。settimeout新增的事件,會在下一次event loop執行。

settimeout(f,0)將第二個引數設為0,作用是讓f在現有的任務(指令碼的同步任務和「任務佇列」中已有的事件)一結束就立刻執行。也就是說,settimeout(f,0)的作用是,盡可能早地執行指定的任務。

settimeout(f,0)有幾個非常重要的用途。它的一大應用是,可以調整事件的發生順序。比如,網頁開發中,某個事件先發生在子元素,然後 冒泡到父元素,即子元素的事件**函式,會早於父元素的事件**函式觸發。如果,我們先讓父元素的事件**函式先發生,就要用到 settimeout(f, 0)。

上面**在點選按鈕後,先觸發**函式a,然後觸發函式c。在函式a中,settimeout將函式b推遲到下一輪loop執行,這樣就起到了,先觸發父元素的**函式c的目的了。

使用者自定義的**函式,通常在瀏覽器的預設動作之前觸發。比如,使用者在輸入框輸入文字,keypress事件會在瀏覽器接收文字之前觸發。因此,下面的**函式是達不到目的的。

上面**想在使用者輸入文字後,立即將字元轉為大寫。但是實際上,它只能將上乙個字元轉為大寫,因為瀏覽器此時還沒接收到文字,所以this.value取不到最新輸入的那個字元。只有用settimeout改寫,上面的**才能發揮作用。

上面**將**放入settimeout之中,就能使得它在瀏覽器接收到文字之後觸發;原來如此:這也就解釋了緣何在使用backbone呼叫render之時,操縱dom是無效的了,因為當時連dom元素都還沒獲取到(為何沒報錯?這牽扯到另乙個話題),自然等頁面渲染完畢了也沒見想要的結果了。

參考: 

setTimeout和Promise執行順序

script 主程式 process.nexttick promise settimeout i 主體部分 定義promise的構造部分是同步的,因此先輸出2 主體部分再輸出6 同步情況下,就是嚴格按照定義的先後順序 ii process.nexttick 輸出5 iii promise 這裡的pr...

params傳參和query傳參

params傳參 this.router.push query傳參 this.router.push 1 用法上的 query要用path來引入,params要用name來引入,接收引數都是類似的,分別是this.route.query.name和this.route.params.name。注意接...

params傳參和query傳參

當你使用params方法傳參的時候,要在路由後面加引數名,並且傳參的時候,引數名要跟路由後面設定的引數名對應。使用query方法,就沒有這種限制,直接在跳轉裡面用就可以。注意 如果路由上面不寫引數,也是可以傳過去的,但不會在url上面顯示出你的引數,並且當你跳到別的頁面或者重新整理頁面的時候引數會丟...