最近在為公司專案寫單元測試,發現了很多之前沒注意到的坑。在爬資料取值時,有非同步的問題,一載入程式碼就做測試,資料都還沒爬回來,一定會報錯,這時如果使用 Promise 可以很輕易解決此問題。
MDN 說明
Promise 會代理一個建立時,不用預先得知的值。它使你能夠繫結(associate)著發動非同步操作後,
最終的成功值(success value)或失敗訊息(failure reason)的處理函示(handlers)。
這讓非同步方法回傳值的方式很像同步方法,但不是回傳最終結果:非同步方法回傳一個 promise 物件作為未來某時間點的值。
大概意思就是用一個狀態 (Promise) 來代表現在非同步操作的成功或失敗,這在使用ajax時非常方便。
ex:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29const getFakeData = (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then((res) => {
let fake_data;
res.json().then(dataJson => {
fake_data = dataJson.fakeData
console.log(fake_data)
if (fake_data !== "Hi!fakeData") {
//錯誤時可用 reject 拋出錯誤
reject('This fakeData is not what I want');
} else {
//拿到正確的值時使用 resolve() 將值傳下去並做接下來的動作(其實還是有點像callback)
resolve(fake_data);
}
});
})
});
}
// 這邊的 .then() 裡面的 fakeData 就是 resolve 傳進來的
getFakeData('./fakeData.json')
.then((fakeData) => {
let dataTag = document.createElement('p');
dataTag.innerText = fakeData;
document.querySelector('body').appendChild(dataTag);
})
上述為簡單的 fetch 資料流程,我們讓 getFakeData() return 一個 Promise,這時就不用去管這個 function 到底抓到資料了沒,因為 Promise (承諾) 如果抓到資料就使用 resolve 將值傳遞 ,如此我們就可以用 getFakeData(...).then(...)
的方式來寫這個 function 正確執行並拿到資料後要做什麼。
就是那麼簡單,發現很多應用都可以使用 Promise 改寫。