[JavaScript] 一次搞懂同步與非同步的一切:一次做幾件事情 — 同步(Sync)與非同步(Async)
全系列共四篇:
一、[JavaScript] 一次搞懂同步與非同步的一切:一次做幾件事情 - 同步(Sync)與非同步(Async)
二、[JavaScript] 一次搞懂同步與非同步的一切:待會叫你 - 回呼函式(Callback Function)
三、[JavaScript] 一次搞懂同步與非同步的一切:非同步解法救星 - Promise(ES6)
四、[JavaScript] 一次搞懂同步與非同步的一切:解法更進化 - Async/Await(ES7)
Outline:
+ 同步是什麼?非同步是什麼?
+ 為什麼需要非同步?什麼時候會用到?
同步是什麼?非同步是什麼?
「同步」這個字常常讓人很混淆,乍看之下好像是「同步做很多事情」,其實剛好相反,如果試著一句話來說明概念,可以想像為:「一次做幾件事情」。
Javascript 是一種「單執行續 (Single-Thread)」的語言,意思就是一次只能做一件事情,如果安排了很多事情要給他做,他就會讓這些事情去排隊,再一件一件做,逐行執行。這就是所謂的同步,一次只做一件事情。
非同步的概念則是剛好相反,同時可以做很多件事情,不需要等到前一件事情做完才做下一件事情。
為什麼 Javascript 可以非同步?
剛剛說 Javscript 是單執行續,那為什麼可以執行非同步事件呢?
因為當我們在執行 Javscript 的時候,Javascript 是在瀏覽器內執行的,
瀏覽器還提供了很多 WebAPI (ex: document、XMLHttpRequest、setTimeout) 給我們使用,他們不在 V8 引擎中,也是我們無法取得的內容,我們只能呼叫這些功能去執行他,當瀏覽器知道你要呼叫他們來用的時候,就可以和你的程式碼同時一起執行 (Concurrency) ,也不會影響到你的 JS 主程式,
所以在瀏覽器內,只有 Javascript 引擎本身是同步的,而 Javascript 引擎可以跟 WebAPI 溝通,達到非同步的事件處理。
想知道更多瀏覽器與 Javascript 怎麼相互溝通非同步事件可以看這裡:
[JavaScript] Javascript 的事件循環 (Event Loop)、事件佇列 (Event Queue)、事件堆疊 (Call Stack):排隊
為什麼需要非同步?什麼時候會用到?
那如果都是同步執行不好嗎?不好,因為這樣你的網頁會塞車,稱為阻塞 (Blocking)。阻塞是一種現象,等得太久了,網頁好像當掉了,點什麼都沒有用,因為上一件事情還沒做完,所以下一件事情等著還沒做。
如果你已經是一位前端開發者,其實你已經運用過很多瀏覽器所提供的非同步方法,舉例:
- 向 API 發送請求:如果沒有非同步執行這些行為,那你呼叫了一支 API,在等待資料回傳的過程中,網頁什麼事都沒辦法執行,連渲染畫面都不行,user 只能等在那裡,那肯定是不行的。
- setTimeout:又或者你曾經使用過 setTimeout 去處理要晚一點發生的事情,這個 setTimeout 會等待你所指定的時間,等到時間到了,再將需要發生的事件丟回 Javascript,讓 Javascript 知道說有這個事情排隊著要來觸發了。
- document:使用 document.querySelector 去獲得你要操作的 DOM 其實也是瀏覽器提供的,是讓 Javascript 可以和瀏覽器溝通的方法。
看過很多網路上同步與非同步的文章,大部分都將這四個主題寫在一起,自己全部一起看總是容易看到出神,所以這次分為四篇文章,可能每篇的篇幅都不會太長,目的就是可以一次一次慢慢吸收,慢慢消化。
內容若有任何錯誤,歡迎留言交流指教!🌴全系列共四篇:
一、[JavaScript] 一次搞懂同步與非同步的一切:一次做幾件事情 - 同步(Sync)與非同步(Async)
二、[JavaScript] 一次搞懂同步與非同步的一切:待會叫你 - 回呼函式(Callback Function)
三、[JavaScript] 一次搞懂同步與非同步的一切:非同步解法救星 - Promise(ES6)
四、[JavaScript] 一次搞懂同步與非同步的一切:解法更進化 - Async/Await(ES7)