先來複習使用 XMLHttpRequest 的正常情況
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'
// 一個錯的 url
// 測試是否非同步
console.log(1)
const request = new XMLHttpRequest();
request.open('GET', api200, true);
// 第三個參數 true,就算未指定預設也是 true 是取得資料的方式為 asynchronously,若為 false 則會設定為同步。
request.onload = function () {
if (this.status >= 200 && this.status < 400) {
let data
try {
data = JSON.parse(this.response)
} catch (error) {
console.log(error)
return
// apiJsonError 的結果
}
console.log(data) // api200的結果
} else {
console.log('Here hava error (ex: 404, 500)from server, but we got repsonese is successful')
// api500 的結果
return
}
};
request.onerror = function () {
console.log('Here have error by request url or others reason')
//apiWrongUrl的結果
}
request.send();
console.log(2)
console.log(3)
//先印出 123 才回傳 api 資料! 非同步,成功!
範例中有設定不同錯的 api url,可以使用該變數去假裝錯誤,好去了解是哪邊產生了錯誤。(Mocky 的 api 連結有效期,過期可以告訴我一聲)
因為目前自己對網路也沒有很熟悉,就現在的能力只能預設會產生的錯誤有 1)回傳的json有錯 (apiJsonError)、 2)當 server 有內部錯誤的時候回傳HTTP status Code 500 (api500)、 3)當自身的url有錯,或者 client 端網路連線有 error 你可以拔掉網路線試試看 (apiWrongUrl)。
或者可以直接使用 api200 一切正常的情況下去跑跑看這段程式。
以上是使用 XMLHttpRequest 的方式串 api,並且看見了console.log(1)
,console.log(2)
,console.log(3)
會先印出來,才會回傳 api 的資料。
先介紹一下 Promise
Promise 會自動生成 resolve
與 reject
function,並且只會回傳其中一個,不是 resolve, 就是 reject。
以下的範例,因為尚未串 API 為範例,只是利用變數 data
來假裝一下是 API 回傳的資料,把data
放入 resolve
function,接著我們執行 myPromise()
會回傳 error Uncaught TypeError: myPromise is not a function
,因為 myPromise 是 Promise 並不是 function ,所以我不能使用 myPromise()
這種方式拿到 data。
我們必須使用 then()
來接收 data,就會拿到這個 "This is fake API data"
😬 。
重點要記住,只要是 Promise ,就是要用 then()
,來接收 data 。
const data = 'This is fake API data'
const myPromise = new Promise((resolve, reject) => {
resolve(data)
})
//myPromise() 這樣是錯的
myPromise
.then(data => {
console.log(data)
})
接著我們來證明是不是非同步的。
如果執行以下程式碼會看到先回傳 1,2,3 才是 "This is fake API data"
const data = 'This is fake API data'
//測試是否同步
console.log(1)
const myPromise = new Promise((resolve, reject) => {
resolve(data)
})
//myPromise() //這樣是錯的
myPromise
.then(data => {
console.log(data)
})
console.log(2)
console.log(3)
但是串 API 很有可能會回傳錯誤,例如我們剛剛 XMLHttpRequest 範例提到的那些錯誤類型,就是要靠 reject
來回傳,並且我們接收 reject 回傳的 error 並不適用 then
,而是我們要在使用 Promise 的時候在 then
後面接上 catch
const data = 'This is fake API data'
const myPromise = new Promise((resolve, reject) => {
//resolve(data)
reject('OMG ERROR') //回傳 OMG ERROR
})
//myPromise() //這樣是錯的
myPromise
.then(data => {
console.log(data)
})
.catch(error => {
console.log(error) // OMG ERROR
})
初步認識了 Promise 之後,下一篇將會展示如何利用 Promise 串 API,再來介紹 fetch, async 與 await 吧。
第一次寫文章不宜太長,分篇寫好了 😆
1 - 非同步之認識Promise
2 - 非同步之Promise串 API
3 - 非同步之認識 fetch
4 - 非同步之認識 async/await