Promise是一個建構函式,與其他可以自定引數的建構函式有點不同的是,它自己帶有resolve與reject函式來傳遞promise的結果。我們在resolve()裡丟一個字串,就像當我們使用fetch()抓資料時,promise fullfilled時會回傳抓到的資料,這裡的字串就等同於那些資料,是promise fullfilled的結果;同樣的,如果再reject丟一個error message,當promise reject時,這個錯誤訊息就會被catch所承接。
const myPromise = new Promise(function (resolve, reject) {
console.log("Async procedure start!");
setTimeout(function () {
if (Math.random() >= 0.5) {
resolve("You win!");
} else {
reject(new Error('You lose..');
}
}, 2000);
});
myPromise
.then((result) => console.log(result))
.catch((error) => console.error(error));
利用建立promise則可以把許多原本是callback base的寫法promise化,可以增進程式的易讀性與可維護性。
下面用兩個例子來說明怎麼把callback base轉成promise base,其中最重要的點在於:想好什麼狀況下會resove與reject,同時兩種狀態到底要回傳什麼東西。像是上面的例子:
這個例子使用瀏覽器提供的web api:geolocation來擷取用戶目前的位置,getCurrentPosition這個方法可以分別引入callback function來處理成功抓到位置和報錯兩個狀態。
navigator.geolocation.getCurrentPosition(
position => console.log(position),
error => console.error('could not access your position')
這樣的callback base的寫法可以改成promise base。
當然,原本的寫法也是可以用,只是用一個promise包起來以後,會更方便後面串接一大堆的then, catch 和finnally,能避免calalback hell,也更好讀這樣。
const getLocation = function () {
return new Promise(function (resolve, reject) {
navigator.geolocation.getCurrentPosition(
position => resolve(position),
() => {
reject(new Error('access failed..'));
}
);
});
};
getLocation()
.then(result => console.log(result))
.catch(error => console.log('reject message', error));
圖片的載入當然是一種非同步程序,我們可以對圖片加上addEventListener,在它的callback裡寫希望載入後作哪些處理,但一樣可以改成promise base讓後面一大串的處理更好讀好維護。
const imgEl = document.createElement('img');
const imgContainer = document.querySelector('.images');
const createImage = function (path) {
return new Promise(function (resolve, reject) {
imgEl.src = path;
imgEl.addEventListener('load', function () {
imgContainer.append(imgEl);
resolve(imgEl);
});
imgEl.addEventListener('error', function () {
reject(new Error('img not found'));
});
});
};
createImage('./img/img-1.jpg');
這個標題是我在開賽前定鐵人文主題時就想用的,因為那時正第一次看promise,覺得..這到底是什麼?這裡大概是我開賽前js的進度了,寫完這幾天,感覺好像自己有更敢於承諾些東西了XD
udemy-The Complete Javascript Course
鐵人賽:使用 Promise 處理非同步