出了點意外沒空寫了,壓底線
有時候會看到技術文寫JavaScript是同步(Synchronous)的,
代表JavaScript的程式會一行一行執行,一次只做一件事,目前的沒執行完不會作下一行程式
但真的是這樣嗎?先來看下面這個方法
setTimeout()
是個計時器,會在傳入的時間後回呼(callback)傳入的程式
像以下例子
setTimeout(() => {
console.log('3秒過了');
}, 3000);
會在3000毫秒(3秒)後在控制台印出文字
setTimeout(() => {
console.log('3秒過了');
}, 3000);
console.log('印出一些東西');
以同步的特性來看,JS應該會等三秒後印出3秒過了
,再印出下面的印出一些東西
但並沒有,打開瀏覽器後會發現瞬間印出印出一些東西
,3秒過後才印出3秒過了
這跟說好的不一樣啊? 難道JavaScript可以一邊計時一邊執行下面的程式碼?
其實不是,JavaScript本身是同步的沒有錯,但執行他的瀏覽器是非同步的,setTimeout()
跟計時是瀏覽器提供的方法。
當使用setTimeout()
時,要執行的函式跟時間會被傳給瀏覽器由瀏覽器來計時處理,
JS本身則會繼續執行下一行程式,等時間到了後瀏覽器在把函式傳回給JS執行。
那這種從外部傳回的任務是甚麼時候會執行?會立刻停止本來的程式立刻去執行嗎?
比如說像這樣
setTimeout(() => {
console.log('3秒過了');
}, 0);
console.log('印出一些東西');
甚至這樣呢
setTimeout(() => {
console.log('3秒過了');
}, 0);
var a = [];
for (let i = 0; i < 9999999999; i++) {
a[i] = i;
//不重要 反正就是一個要花好幾秒執行的程式碼
}
console.log('印出一些東西');
答案是3秒過了
永遠會比印出一些東西
晚印出
這些外部的事件在返回時不會直接給JS執行,而是進入一個叫做事件佇列(event queue)的地方,
以前提過JS是以呼叫堆疊來追蹤程式執行,當主程式執行完且呼叫堆疊為空時,
JS才會檢查事件佇列,把佇列內的任務放進呼叫堆疊來執行。
明日繼續