實際上的最後一篇學習筆記,明天是使用的學習資源推薦跟個人反省會
Promise(承諾 或是約定)是ES6新增的一個物件
再開始講Promise(前先用簡單的比喻形容一下callback跟Promise的差別
假如今天想要花錢叫個漢堡外送
callback就是你打電話過去麥O勞,
跟他說一句我想要一個大O克餐,做好後到我家門口按電鈴再跟我收200元
然後就掛了電話。
如果沒甚麼問題的話,會收到一份大O克並付200元。
但有可能出了問題,他送了一個麥O雞餐過來拿走你的200元,
或著出現五個外送員拿著五個大O克餐各跟你收200,
或著再也沒有回應了,你不知道大O克餐到底會不會來。
Promise的話就是你用UbOrEOt叫了一份大O克餐並使用現金付款,
叫完後他會給你一筆訂單確定你成功下單了。
你可以看到這筆訂單就去做其他事,順便想著等等有人來按門鈴的話就去開門付錢,
或是UbOrEOt通知大O克賣完了只能取消,
又或著超過半小時沒來的話手動取消訂單,自己出門去買消夜。
callback基本上是把控制權交給外部,而Promise則是依照外部的結果來處理接下來的動作
...廢話講多了 還是來寫程式吧
先建立一個Promise物件印出來看看
const Psample = new Promise((resolve, reject) => {
});
console.log(Psample);
建立一個Promise,要傳入兩個函式(resolve跟reject,不需要我們宣告)當參數,
如果這個Promise成功實現了,則呼叫resolve函式,當失敗或出現錯誤時會呼叫reject
接著來看印出來的結果
會看到Promise有兩個屬性
首先是[[PromiseState]],這個代表承諾目前的狀態,狀態有三種情況pending(未定)
:代表承諾還在處理中fulfilled(達成)
:resolve被呼叫,代表承諾達成了rejected(否決)
:reject被呼叫,代表承諾被否決了
目前上面的Promise沒有任何呼叫resolve或reject的內容,所以目前的狀態為pending
const Psample = new Promise((resolve, reject) => {
resolve();
});
console.log(Psample);
不做甚麼事直接呼叫resolve,會看到[[PromiseState]]變為fulfilled(已達成)
另外Promise的狀態一但達成或被否決,狀態就不會再被改變了
像這個樣子
const Psample = new Promise((resolve, reject) => {
reject(); //先否決
resolve(); //再達成
});
console.log(Psample);
變為rejected後就不會再更動了
另一個值為[[PromiseResult]],這個是承諾的結果值,會在呼叫resolve或reject當作參數接收
const Psample = new Promise((resolve, reject) => {
resolve('結果值');
});
console.log(Psample);
會看到[[PromiseResult]]的內容變為結果值
了
當Promise有結果後,傳入then()方法回呼函式會自動被觸發,
如果有[[PromiseResult]]的結果會被當作參數傳入回呼函式
語法
Promise.then(成功時回呼的函式,失敗時呼叫的函式)
這樣解釋起來還是很難懂,還是用範例
function makeAPromise() { //一個回傳Promise的函式
return new Promise((resolve, reject) => {
setTimeout(() => {
const random = Math.random();
if (random > 0.5) {
resolve(random);//成功
} else {
reject(random);//失敗
}
}, 1000);
});
}
makeAPromise().then( //呼叫函式建立Promise
(value) => {//成功的話會呼叫這裡
console.log('大於0.5?,你的數字' + value);
},
(value) => {//失敗的話會呼叫這裡
console.log('小於0.5?,你的數字' + value);
}
);
makeAPromise()這個函式會建立一個Promise,會在一秒後隨機個0~1的數字,
再以這個隨機數來決定這個Promise是達成還是被否決,再依結果值行then()內的回呼
上面結果會在一秒後印出
then()方法可以只傳入一個函式(成功時回呼),
回呼如果有return一般值時,會自動回傳一個新的Promise(自動成功)跟值,
代表可以在後面直接加上then()來處理新的Promise成功要做的回呼,
並且能接收return值當作參數來使用
以下是用then的串接來模擬鐵人賽想題目->找資料->寫文->完成的一步一步動作
function makeAPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const random = Math.random();
if (random > 0.1) {
resolve();
} else {
reject();
}
}, 1000);
});
}
makeAPromise()
.then(() => {
console.log('想好題目了');
return 'Promise';
})
.then((v) => {
console.log('開始找參考');
return { theme: v, data: '相關資料' };
})
.then((v) => {
console.log('開始寫文');
return { theme: v.theme, data: v.data, article: '(文章內容)' };
})
.then((v) => {
console.log(
`寫好了! 題目為:${v.theme} 內容:${v.article} 參考資料:${v.data} 可以發文了`
);
})