若要在前端網站發 AJAX Request,有兩種方法
法一、XML HTTP Request,簡稱 xhr
法二、Fetch
要串 api 練習,但沒有 api 怎麼辦 ?
透過mocky,可以自己創造出一個 response,然後就可以自己抓 response 回來。
Fetch 怎麼用 GET
fetch(網址) === 發 request
<script>
fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
</script>
接著想看,call 這個 funct 會回傳甚麼東西
<script>
const result = fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
console.log(result)
</script>
回傳後出現了 promise。promise 是一個物件的類型,比如說使用 jQuery 時,$(.button)
這個 function 回傳的會是一個 jQuery 的物件,Promise 也是一個獨特的物件,就跟正規表達是 RegExp 也是一個獨特的物件一樣。fetch 會回傳 Promise 這個獨特的物件,但其他的 functon 也可能會回傳 Promise。
要拿到 Promise 的結果,要使用 .then()
,括號內要接的是一個 callback function。
<script>
function printResult(a) {
console.log(a)
}
const result = fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
result.then(printResult)
</script>
a 會是一個 response,我們成功拿到回傳的結果。
可以簡化上述 code
fetch('https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372')
.then((a) => {
console.log(a)
})
取 response 的 status
<script>
const api500 = 'https://run.mocky.io/v3/c5989253-8bcf-4f6a-970a-c393cdd5090e'
const api200 = 'https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372'
function printResult(a) {
console.log(a)
}
fetch(api500)
.then((response) => {
console.log(response.status)
})
</script>
絕大多數時候,我們想要的是 response 的內容,直接 console.log(response.body)
會出現 => ReadableStream,會不知道怎麼讀他。所以 response 上面提供了幾個方法
法一、response.text() => 回傳的會是 promise
const api500 = 'https://run.mocky.io/v3/c5989253-8bcf-4f6a-970a-c393cdd5090e'
const api200 = 'https://run.mocky.io/v3/82ec874a-086c-48ef-8195-37686b61f372'
function printResult(a) {
console.log(a)
}
fetch(api500)
.then((response) => {
response.text().then(text => {
console.log(text)
})
})
法二、response.json() => 回傳的會是 promise
與法一的不同在於,會將 response 的內容用 json.parse 變成一個 json 的字串。
他相當於是法一做了這件事
.then((response) => {
response.text().then(text => {
console.log(JSON.parse(text))
})
})
fetch() 回傳的會是 promise
response.text()、response.json() 回傳的也會是 promise
response.json().then() 回傳的還是 promise
promise 要拿資料必須透過 .then() 括號接 cb function 就可以拿到資料
.then() 無窮無盡 Chaining
.then 裡面又 .then 很難閱讀,所以可以利用 promise 的神奇特性
用 .then return 的東西會是下一個 .then 裡面的值。如果 return 是 undefined,.then 裡面的值就是 undefined。
fetch(api200)
.then((response) => {
console.log(response.status)
response.text().then(text => {
console.log((text))
return 123
}).then((abc) => {
console.log('abc', abc) //abc 123
})
})
不 return 任何東西,預設就是 undefined,所以 abc 就是 undefined
fetch(api200)
.then((response) => {
console.log(response.status)
response.text().then(text => {
console.log((text))
}).then((abc) => {
console.log('abc', abc) //abc undefined
})
})
為甚麼 .then() 完還可以再 .then() ?
因為 .then() 也是一個 function,所以 .then() 這個 function 回傳的還是一個 promise,所以可以再繼續接續下去。
這跟這個很像,當我們呼叫 css 這個 function,這個 function 的回傳值是另外一個 jQuery 的物件,所以她又可以再 .hide(),.hide() 回傳的也是一個 jQuery 的物件,所以可以再 .show(),因為一直 return 自己,才可以做到這樣的事情,我們叫他 chaining。
$('.button').css(...).hide().show()
return 的東西如果是 promise,那我再下一個 .then 拿到的值,就會是解析完的值
這個 text 是 response.text() 這個 promise 的回傳值。
response.text().then(text =>)
我拿到的 abc 就會是 response.text() 的結果
fetch(api200)
.then((response) => {
return response.text()
}).then(abc => {
console.log(abc)
})
可以利用這個特性,縮排較少,更好閱讀拿到資料。cb 大時代極力避免很多層、縮排很多,因為會很難追蹤程式碼。
重點回顧
- return 的是值,他會自動帶到下面去
- return 的是 promise,會將 promise 解析完後,用 .then 的方式拿出來的值,帶到下面去。(可以利用這樣的方式,拿到 json 格式的資料)