非同步(asynchronous)
是 JavaScript 非常重要的概念之一,如果不理解非同步的特性甚至不會使用,在實際開發上絕對會處處碰壁。但在開始之前,還是先從 同步(synchronous)
的概念開始說起吧。
首先我們要了解的是:JavaScript 是單執行緒(Single-threaded)
語言,也就是說程式碼在任何特定時間只能執行一個操作。也就是說,JavaScript本身無法在同一時間處理多件事。
而同步(synchronous)
的意思是程式碼會按照順序的逐行執行,並且只有前面的程式碼處理完畢,才會繼續執行下一行程式碼。
來看看以下範例:
console.log('檢查點A');
alert('Hello World!');
console.log('檢查點B');
這段程式碼是同步處理的,一開始會印出"檢查點A",之後會彈出警告視窗,而在關閉視窗前,後面的程式碼是不會被執行的(不會印出"檢查點B")。
同步操作很直覺,但它不是萬能的,可能會帶來阻塞
的缺點。
阻塞
是指同步操作的情況中,如果某個操作需要花費較長時間完成,將導致整個程式將停滯不前,無法執行其他操作。這對於應用程式來說是一個重大問題,因為它會導致體驗不佳。
例如,當程式碼需要等待某些資源或請求完成時(載入長影片等),同步操作會導致長時間的阻塞,而且載入完成前瀏覽器是無法重新渲染畫面的(畫面卡住),這非常影響使用者體驗。
為了解決上述問題,就要用到非同步
。
非同步(asynchronous)
允許程式碼在執行其他操作時繼續監聽和處理可能需要花費較長時間的動作,而不必等待它們完成。這使得 JavaScript 能夠處理非同步任務,例如網絡請求、計時器、事件處理等,同時保持程式的響應性和效能,以保持較好的使用者體驗。
不過非同步(asynchronous)
也不是三言兩語就能摸清的,這裡就先舉簡單的例子就好。
// day08 - 非同步範例一
console.log('檢查點A');
setTimeout(function() {
console.log('Hello World!');
}, 5000);
console.log('檢查點B');
關於setTimeout
的參數跟用法就不詳述,我們先知道setTimeout
是非同步的,且這裡的setTimeout
作用是在5秒(5000豪秒)之後印出"Hello World!"。那這段程式碼的輸出順序如何呢?答案如下:
檢查點A
檢查點B
Hello World!
上述程式碼示範了非同步的作用,一開始印出"檢查點A"後,它不必等待5秒,而是先處理印出"檢查點B"的程式碼。而到了5秒後才會印出"Hello World!"、
再來看另一個相似的例子:
// day08 - 非同步範例二
console.log('檢查點A');
setTimeout(function() {
console.log('Hello World!');
}, 0);
console.log('檢查點B');
這裡的setTimeout
作用是在0豪秒之後印出"Hello World!"。0毫秒好像不需要花費時間等待耶,那實際的輸出順序是如何呢?答案如下:
檢查點A
檢查點B
Hello World!
我們會發現"Hello World!"竟然還是最後才印出的!這是因為非同步的程式碼一定會等到當前的同步程式碼都處理完畢
才會執行。這概念非常重要!關於JavaScript在瀏覽器中的同步與非同步是如何互相配合的,我會在明天的事件循環(Event Loop)
做更深入的介紹。
那今天先在這邊告一段落,我們明天見~