這是 Fetch, Promise, Async & Await 的 第二篇,有興趣的朋友可以先看 非同步之認識Promise。
上一篇有簡單介紹 Promise 之後,我們可以使用 Promise 來串 API 試試看,API URL 一樣是使用上一篇的網址,如果有過期問題記得提醒我,謝謝!
Promise 串 API
先來長長的範例如下:
const api200 = 'https://run.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 完全正常運作的 server
const api500 = 'https://run.mocky.io/v3/bf2b926c-0db4-4f98-b09a-1211d4da6038'
// 假裝 server error 回傳 500 的 api
const apiJsonError = 'https://run.mocky.io/v3/3bf6bbd8-6b7c-47f7-8b92-9efb2a0a8dfc'
// 回傳 200 但是 json 格式錯誤的 api
const apiWrongUrl = 'https://srun.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 新建 promise
const requestPromise = new Promise((resolve, reject) => {
var request = new XMLHttpRequest();
request.open('GET', api200, true);
request.onload = function () {
if (this.status >= 200 && this.status < 400) {
let data
try {
data = JSON.parse(this.response)
} catch (error) {
reject(error) // apiJsonError 的結果
return
}
resolve(data) // api200的結果
} else {
reject(request.statusText)
// api500 的結果 : Internal Server Error
return
}
};
request.onerror = function () {
reject('request 有錯囉')
//apiWrongUrl的結果
return
}
request.send();
})
.then(data => {
console.log(data)
})
.catch(error => {
console.log(error)
})
此範例變數使用 api200 ,所以會成功執行 resolve(data)
,我們可以直接在後面接上 then
來接收 API 回傳的 data,也可以不用再後面直接加上去另外拆開寫成這樣也是可以
requestPromise.then(data => {
console.log(data)
})
.catch(error => {
console.log(error)
})
如果帶入其他三個錯誤的 API 變數的話,都會 reject
,我們 then
的後面加上 catch
,就可以接收 reject 傳過來的錯誤訊息。
你可能會想,那這樣有什麼好處呢? 有,我們可以利用 Promise 的語法來一直串 API,我們改寫一下 requestPromise 是可以接收參數,接著我們就可以利用這個參數,來串很多次的 API。
先新增一個變數來放 API URL,並且改寫一下 requestPromise
const api200 = 'https://run.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 完全正常運作的 server
const api500 = 'https://run.mocky.io/v3/bf2b926c-0db4-4f98-b09a-1211d4da6038'
// 假裝 server error 回傳 500 的 api
const apiJsonError = 'https://run.mocky.io/v3/3bf6bbd8-6b7c-47f7-8b92-9efb2a0a8dfc'
// 回傳 200 但是 json 格式錯誤的 api
const apiWrongUrl = 'https://srun.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
const apiUser = 'https://reqres.in/api/users'
// 新建 promise
const requestPromise = (apiURL) => {
return new Promise((resolve, reject) => {
var request = new XMLHttpRequest();
request.open('GET', apiURL, true);
// ... 以下與上個範例一樣
}
requestPromise(api200).then(data => {
console.log(data)
return requestPromise(apiUser)
}).then(userData => {
console.log(userData)
})
.catch(error => {
console.log(error)
})
可以看到我們可以利用 return 回傳一個 Promise ,接著就可以繼續 then 來串 API 剛剛加入的 API,非同步測試的 console.log ,就不示範了,可以自己 console 試試看。
以上介紹完簡單的 Promise 以及利用 Promise 來串 API 後,我們可以知道 Promise 可以讓我們做到非同步來執行程式,但其實我們還有更方便的 fetch 可以用。
來,再一篇。
1 - 非同步之認識Promise
2 - 非同步之Promise串 API
3 - 非同步之認識 fetch
4 - 非同步之認識 async/await