雖然 Event Queue 不是 AJAX 裡面的東西,不過他們倆息息相關,所以就放在一起介紹了。(是說要介紹這些東西沒放在一起講感覺也少了什麼吧@@?
JavaScript 是一個單線程的語言,也就是說他一次只能做一件事情。而 Event Queue 則是讓他看起來能一次做很多件事情。
以這個範例來說:
// console a
console.log('a');
// 3秒後執行 run() 來 console b
function run() {
console.log('b');
}
setTimeout(run, 3000);
// start 紀錄當前時間,而 while 迴圈裡面的 Date.now() 減去 start 小於等於5000的話就會持續執行
// 換句話說,等到過了5秒就會跳出 while 迴圈,並且執行 c
var start = Date.now();
while(Date.now() - start <= 5000) {};
console.log('c');
顯示的結果會先跑出 a,而 b 與 c 會同時出現。因為 JS 是單線程的關係,所以在 b 還在等待3秒時間的時候,JS 程式碼還是會繼續往下跑,跑完 c 的5秒後,b 的3秒早就跑完準備執行了,因此才會有兩個一起執行的錯覺,這就是 Event Queue 所造成的時間差。
所以把上述具現化應該長成這樣
同步的優點在於會將網頁呈現好才會渲染給用戶觀看,缺點在於如果抓取的資料過大會造成網頁 UI 顯示異常。
非同步的優缺點就正好與同步相反,雖然剛載入頁面時可能有些資料還沒顯示,但並不會使網頁完全無法運作。
昨天有提到目前常見的底層有 XMLHttpRequest 與 fetch,下面就要來介紹關於這兩個 get(抓取) 與 post(發送) 的方法。
一般來說常見到像昨天那樣使用 .onload()
事件來取得資料,不過下面就改使用 addEventListener()
。
就像一般 AJAX 的使用方法一樣,不過這裡寫一下如果想要先看一下回傳的資料
xhr.addEventListener('load', function(){
console.log(this.responseText);
});
有個專門的 load 來做為事件,會在取得資料後返回。
將 open('get', '網址', false)
的第三個參數改為 false 就會轉變為同步,
因為使用 load 事件的話會建議你不要使用同步,否則會造成用戶體驗不佳
因此直接在 send()
後面直接 console.log(xhr.responseText)
即可。
post 請求最直觀的是網址後面不會有 ? 問號。
步驟都差不多,就是 open()
的時候把參數給成 post,不過 post 可以把帶入參數傳回去
發送請求並要求攜帶參數,需要先宣告 var data = new FormData();
並在之後用 data.append(key, value)
來帶入一個 key 以及他的值。
設定好後,在 send()
中將他帶入,多個 append()
就可以帶多個參數。
要注意的是 new FormData()
並不在 JS 單線程的範圍內,他與 setTimeout、AJAX 等等都屬於 WebAPIs。
參考同步 GET
用法:
fetch('網址').then(response => {
return response.json
}).then(data => {
console.log(data)
})
第一個 then()
用於解讀 json 資料,等到解讀完畢後使用第二個 then()
來顯示資料。
用法跟 GET 類似,但要在網址後面新增第二個參數。第二個為一個物件。
{
method: 'POST',
body: data
}
發送方法改為 POST,body 表示帶入的參數。
帶入參數新增的方式也是一樣,
宣告 var data = new FormData();
再用 data.append(key, value);