14-2 setTimeout, clearTimeout 延時執行程式
Lesson: 14-2 setTimeout, clearTimeout 延時執行程式
14-2 setTimeout, clearTimeout 延時執行程式
Original: https://course.andys.pro/Javascript-Intro/14-2-settimeout-cleartimeout-delay-execution-program/
講義
1. setTimeout() 基本語法
setTimeout 用於在指定的延遲時間後,執行一次特定的程式碼。
- 語法:
setTimeout(function, delayInMilliseconds) - 單位:以毫秒 (ms) 為單位,
1000毫秒等於 1 秒。 - 範例:
setTimeout(() => { console.log("三秒到了"); }, 3000);
2. 取消計時:clearTimeout()
當你呼叫 setTimeout 時,它會回傳一個 計時器編號 (Timeout ID)。你可以利用這個編號在時間到達之前取消該任務。
- 範例:
var timerId = setTimeout(myFunc, 5000); // 如果在五秒內執行以下這行,myFunc 就不會被執行了 clearTimeout(timerId);
3. 非同步執行的特性
setTimeout 是非同步的,這代表它「不會」阻塞後續程式碼的執行。
- 如果你設定三秒後執行 A,程式會立刻跳去執行後面的 B,等三秒過後才回頭跑 A。
4. 實戰陷阱:迴圈中的 setTimeout
在 for 迴圈中使用 setTimeout 時要特別小心環境變數的問題:
- 錯誤現象:如果你想每秒印出 1, 2, 3,結果可能印出三個 4。這是因為迴圈早已跑完,變數已經變成了最後的值。
- 最佳解法:在宣告迴圈變數時使用
let而非var。因為let有區塊作用域,能確保每個計時器拿到的是當下的變數副本。
影片逐字稿 (AI 生成)
好 接下來我們進入十四之二setTimeout用法setTimeout的基本語法setTimeout的回傳值還有clearTimeout的方法好的 首先我們來看一下setTimeout的基本語法它這邊呢會有一個function然後這邊是毫秒然後還有一些參數好的它只執行一次 就是就是時間過後它就去執行或是有另外一種語法是你這邊可以放code然後後面是放毫秒可是請記得喔 你這邊的code要怎麼做你這邊code要放雙引號就是把它變成一個自串把code放在自串裡面好的 我們來看一下實際的code是怎麼樣呢我們這邊有一個匿名韓式嘛 對不對這邊這邊寫是一個function然後這個function會說Alert Hello然後是三秒以後就做這件事情好我們copy一下那還是回到剛剛的那一句話我不太想要用Alert因為其實Alert很煩人就是就這樣講好了你如果今天用Alert然後你如果執行多次的話你的電腦可能會比如說它可能會卡掉因為它會一直跳出來一直跳出來所以我們這邊把它趕成ponsollog好那這樣子我們跑的話等一下再數一下123好不好123Hello有沒有有嗎有感受到123Hello嗎再來一次123Hello我為什麼好像比較長還是我123太快好所以它這三秒後它就會執行裡面要的東西OK嗎就是setTimeout好那我也可以用另外另外第二個寫法就是我把這邊變成像自串的寫法然後我們把Alert把它改成ponsollog1 2 3HelloOK嗎這邊都是測試三秒後跑出來然後這邊TimeoutID是64然後是6362好TimeoutID是正整數代表計時器的編號好接下來我們來講ClearTimeout的方法然後它是一個停止setTimeout的方法執行函數首先我們這邊有一個叫做Hello3秒後會執行再來我們再設另外一個setTimeout它是2秒後它就會執行了然後它在執行之前的第一行的 function裡面它會幹什麼它會ClearTimeout Hello所以它會把前面這個清掉那請問這個Hello的Alert Hello會不會跑不會嘛因為我們已經在這裡把它Clear掉了對不對我先見它它3秒後會跑可是我在第二個這個這邊呢它第二秒的時候就已經先執行把下一秒要執行的東西先砍掉然後然後警報說Don Hello然後他跟我講Don HelloOK嗎那如果說我們沒有這一行的話那我們會怎樣呢我們這樣跑然後他會先給我Don Hello再一秒HelloOK嗎所以在這邊它不見就用setTimeout不見得後面的會比較就是它在執行的時候其實是這個先執行後面這個在執行可是這個執行它其實會等2秒然後跑出來然後這等3秒再跑出來OK嗎好的那所以我們要寫一個我要Demo好每秒印出數字的一個HTML透過回圈setTimeout來實作5秒鐘內每秒依序ConsoleLog5秒鐘它要回圈嘛所以呃我們要用一個什麼我們要寫一個for然後let i然後i小於5然後i++然後我們在裡面要幹嘛呢沒關係我們就直接來寫吧好的它要是一個叫做print numberHTML所以我們要建一個print numberHTML然後我們驚探號是不是先建一個這樣子的東西先建一個HTML然後裡面不用有任何東西嘛它只要Console會印東西就好所以我們在這邊寫一個script然後我們在script裡面呢我們是用for回圈然後for var i等於0i小於5i++然後在這邊呢我們寫一個setTimeout然後setTimeout裡面要有一個function這個function裡面要幹嘛呢這個function裡面要跑說ConsoleLog然後它要幹嘛它要印出01234好所以這邊我們要印就蠻簡單的嘛就是i對不對那比較困難一點是在於秒數那秒數呢我們是不是應該就要因為它是要馬上就執行嗎5秒鐘之內01234是第5秒印4還是等一下它是第5秒印4還是沒有吧那我們我們就直接用i對不對我們是從0到4嘛對不對所以我們直接乘以1000記得喔因為它是毫秒所以我們用1000好不好好然後這時候呢我們就這邊我們寫好了以後呢我們到檔案裡面我們去跑這個那我們去看它的Console那同學有可能會覺得說那我最近都跑完了喔喔喔寫錯了嗎喔寫錯了好SET INTERROR就是會一直重複嘛所以剛才就爆掉SET TIME UP把它存檔把它存檔好不然那頁面不見好我要重新打開然後我們看一下欸我寫錯了i然後i所以我的i沒有傳進去啊它好像都是拿到最後一個i對不對我們看一下怎麼把它傳進去所以我如果這邊wire一個在這邊建議一個ii這樣可以嗎這樣可以嗎這樣不行我們看一下怎麼把子傳進去所以我們看到我們現在我們可以開門去我們要看去選擇我們要來開門去那裡我們可以開門去我們要開門去我們要開門去我們要開門去我們要開門去OK那所以我們如果把這邊我們先建一個I然後我們先建另外一個值叫J等於0用VAR鍵然後我們在這邊呢我們就會印出在這個Function裡面呢我們就會印出J然後我們在這裡對J加加好這樣就可以了OK嗎我們剛開始在這邊現在外面先建一個J然後它在這個Function裡面它拿到的是什麼它拿到是這個0嘛對不對那它跑一次的時候它才會對這個值去增加然後它是拿到外面這個值所以第一秒它就跑印出來0然後把它加加1然後第二秒再跑再跑再跑再跑OK嗎那我剛剛那邊為什麼會想錯因為其實呢你這個程式在跑的時候你這個程式在跑的時候它已經這個Ford回線早就已經結束你這個01234的這個時間軸我們來看就是說你的I等於0I等於1對不對這個跟這個間隔可能只有比如說我們例如好了5毫秒好了好不好5然後這樣子它是不是還要跑下一個那其實它是setInterval是我在這邊我執行了setInterval我是在這邊的第一比如說第一個是第0秒對不對這是setInterval對不對然後它在這邊它會去因為我已經有給它一個Function對不對它這個Function它是在這邊第一個這是第一個然後再來這邊呢它就說1秒後所以在這邊這邊可能是1秒然後第一個這一個才是這邊這個是2秒那可是這一個Function執行的時候這個Function執行的時候可能這個像我們剛才一開始的時候i就是5了因為這個Function執行就跑這Function執行很快就跑完它設定幾個它要做的事情的時間點那所以你其實拿它的i來應的話你就會得到4個你就會得到5個5555555因為這個Function做完了以後它這邊做了5個Function要結束了這時候i就等於5然後那時候才會去跑這個Function才去跑第2個才去跑第3個才跑第4個才跑第5個才跑第5個這時候i都是5就是說你這個Function跑完i值是不是5大家可以理解嗎那settimeout那個Function被call的時候其實4已經都做完了所以才會出現我剛剛那個很奇怪的狀況就是就是都是555次嘛對不對那我現在這邊這個做法是我在前面先建一個j然後j是0他執行這個執行了以後他才加1對不對那時候他就1剛開始的時候0這裡1這裡2這裡3這裡4可以理解嗎我的settimeout就算我是第0秒還是跑都是在4之後在這邊我才跑裡面那個Function裡面那個Function被call了就裡面這個Function被call了匿名還是一巴掌相對這個settimeout這個是在這個的後面那有可能像我們剛才後面不是有一個就是他是在他後面才跑所以你要裡面的J就是你要用獨立的方法就是來跑這樣子OK好了這邊是14-2
影片逐字稿largev2
接下來我們進入14-2SetTimeout的基本語法SetTimeout的回傳值還有ClearTimeout的方法首先我們來看一下SetTimeout的基本語法這邊會有一個Function然後這邊是毫秒然後還有一些參數他只執行一次就是時間過後他就去執行或是有另外一種語法是你這邊可以放Code然後後面是放毫秒可是請記得喔你這邊的Code要怎麼做你這邊的Code要放雙引號就是把它變成像一個字串把Code放在字串裡面我們來看一下實際的Code是怎麼樣呢我們這邊有一個匿名函式嘛這邊寫是一個Function然後這個Function會說Alert Hello然後是三秒以後去做這件事情那我們Copy一下那還是回到剛剛的那一句話我不太想要用Alert因為其實Alert很煩人就這樣講好了你如果今天用Alert然後你如果執行多次的話你的電腦可能會比如說他可能會卡掉他會一直跳出來所以我們這邊把它改成Console.log那這樣子我們跑的話等一下來數一下123好不好123Hello 有了 有沒有有嗎 有感受到123Hello嗎再來一次123Hello為什麼好像比較長還是我的123太快好 所以他就三秒後他就會執行你裡面要的東西OK嗎就SetTimeout好 那我也可以用另外第二個寫法就是我把這邊變成像字串的寫法然後我們把Alert把它改成Console.log好123Hello OK嗎這邊都是測試三秒後跑出來然後這邊Timeout ID是64然後是6362Timeout ID是正整數代表計時器的編號OK接下來我們來講ClearTimeout的方法然後他是一個停止SetTimeout的方法執行函數首先我們這邊有一個叫做Hello 三秒後會執行再來我們再設另外一個SetTimeout他是兩秒後他就會執行了然後他在執行之前的第一行的function裡面他會幹什麼他會ClearTimeout Hello所以他會把前面這個清掉那請問這一個Hello的Alert會不會跑不會嘛,因為我們已經在這裡把他Clear掉了我先見他,他三秒後會跑可是我在第二個這邊呢他第二秒就已經先執行把下一秒要執行的東西先砍掉然後警報說Don’t Hello然後他會跟我講Don’t HelloOK嗎那如果說我們沒有這一行的話那我們會怎樣呢我們這樣跑然後他會先給我Don’t Hello再一秒HelloOK嗎所以在這邊他不見,就因為有用SetTimeout不見的後面的會比較就是他在執行的時候其實是這個先執行後面這個再執行,可是這個執行他其實會等兩秒跑出來,然後這是等三秒再跑出來OK嗎好的所以我們要寫一個我要Demo每秒印出數字的一個HTML透過回圈SetTimeout來實作五秒鐘內繼續Cancel Log五秒鐘,他要回圈嘛所以我們要用一個什麼我們要寫一個for然後let i,然後i小於5然後i++然後我們在裡面要幹嘛呢沒關係我們就直接來寫吧好了,他又是一個叫做Print Number HTML所以我們要建一個Print Number的HTML然後我們驚嘆號是不是先建一個這樣子的東西先建一個HTML然後裡面不用有任何東西嘛他只要Cancel會印東西就好所以我們在這邊寫一個Script然後我們在Script裡面呢我們是用for回圈然後forvar i等於0i小於5i++然後在這邊呢我們寫一個SetTimeout然後SetTimeout裡面要有一個Function這個Function裡面要幹嘛呢這個Function裡面要跑說Cancel Log然後他要幹嘛,他要印出01234好,所以這邊我們要印就蠻簡單的嘛,就是i對不對那比較困難的點是在於秒數那秒數呢我們是不是應該就要因為他是要馬上就執行嗎5秒鐘之內01234要5嗎5秒之內是第五秒印4還是他是第五秒印4還是沒有吧那我們就直接用i我們是從0到4嘛所以我們直接乘以1000記得喔,因為他是毫秒所以我們要用1000好然後這時候呢我們就這邊我們寫好了以後呢我們到檔案裡面Open那我們去看他的Console那同學可能會覺得說那我這已經都跑完了喔喔喔寫錯了嗎喔寫錯了好,所以Interval就是會一直重複嘛所以剛才就爆掉Set timeout好我發現他頁面不見了好,我要重新打開然後我們看一下欸我寫錯了i,然後Console.log i所以我的i應該沒有傳進去喔他好像都是拿到最後一個i對不對我們看一下怎麼把他傳進去所以我在,我如果這邊Wire一個在這邊建一個ii這樣可以嗎這樣不行我們看一下怎麼把值傳進去OK那所以我們如果把恩這邊我們先建一個i然後,欸我們先建另外一個值叫j等於0用Wire建然後我們在這邊呢我們就會印出在這個function裡面呢我們就會印出j然後我們在這裡對j++好,這樣就可以了OK嗎我們剛開始在這邊先在外面先建一個j然後他在這個function裡面他拿到的是什麼他拿到的是這個0嘛對不對那他跑一次的時候他才會對這個值去增加然後他是拿到外面的這個值所以第一秒他就跑印出來的0然後把它++1然後第二秒再跑這樣子那我剛剛那邊為什麼會想錯因為其實呢你這個程式在跑的時候他已經這個forward回線早就已經結束你這個0,1,2,3,4的這個時間軸我們來看就是說你的i等於0i等於1對不對一秒後所以在這邊這邊可能是1秒然後這一個才是這邊這個是2秒那可是這一個function執行的時候可能這個像我們剛一開始的時候i就是5了因為這個forward回線很快就跑完他設定幾個他要做的事情的時間點那所以那所以你其實拿他的i來印的話你就會得到你就會得到五個5嘛因為你這個forward回線做完了以後他這邊做了五個forward回線就結束了這時候i就等於5然後那時候才會去跑這個function才去跑第二個才去跑第三個才跑第四個才跑第五個這時候i都是5就是說就是說你這個forward回線跑完的時候i值是不是5大家可以理解嗎那setTimeout那個function被call的時候其實forward已經都做完了所以才會出現我剛剛那個很奇怪的狀況就是就是都是印55印5次嘛對不對那我現在這邊這個做法是我在前面先建一個j然後j是0他執行這個執行了以後他才加1在這裡的時候他就印1剛開始的時候0這裡1這裡2這裡3這裡4可以理解嗎我的setTimeout就算我是第零秒開始跑都是在for之後在這邊我才跑裡面那個function被call了就裡面這個function被call了匿名函是一巴掌的象徵這個setTimeout是在這個的for的後面那有可能像我們剛才後面不是有一個就是他是在他後面才跑所以你要裡面的j就是你要用獨立的方法就是來跑這樣子ok好了這邊是14-2