Promise 的好用之處在於,可以確保事件完成後再執行後面的行為,也解決了傳統 callback 波動拳的問題。它用 resolve, reject 來傳遞函式執行後為成功或是失敗的訊息,再用 then 與 catch 來做對應處理。這一篇就用範例快速了解一下 Promise 怎麼用吧!
情境舉例:
當我要去旅遊,首先必須先整理行李後才能出發,
因此行李整理完成,我才會叫車
Promise 基礎範例
1 | function checkLuggage() { |
迴圈與 Promise, Promise.all 的運用
Promise.all() 這個方法可以同時執行很多 Promise,並在全部都執行完後回傳。
情境舉例:
繼續上一個情境,整理行李要拿的東西實在太多
假設我只要發送指令,就可以讓機器人自動去幫我做拿好(做夢
那整理行李這件事,我就可以個別發送『拿衣服』、『拿褲子』、『拿襪子』指令,讓他們去拿 XD
當我發送出指令的時候,我總要知道他們哪時候完成,才方便我打電話叫車嘛~
此時就可以用 promise.all 來確定事情完成:
先制定好去拿的這個事件,並在完成拿取時回報完成
1
2
3
4
5
6let todos = ['拿衣服', '拿褲子', '拿襪子'];
function getThing(todo) { // 拿東西都是相同指令,就用同一個函式就可以了
return new Promise((resolve, reject) => {
setTimeout(resolve, 10000 * Math.random(), todo+'完成');
})
}接著用 checkLuggage 來統一發送與接受完成的回傳:
1
2
3
4
5
6
7
8
9
10
11
12function checkLuggage() {
return new Promise((resolve, reject) => {
let allTodo = []; // 用一個變數將所有 promise 事件推進去
todos.forEach(todo => {
allTodo.push(getThing(todo));
})
Promise.all(allTodo).then((results) => {
const msg = '全部完成:'+ results;
resolve(msg);
})
});
}最後執行 checkLuggage 函式,等到全部事情都完成了才會執行 callForCar 函式
1
2
3
4
5
6
7function callForCar() {
console.log('叫車')
}
checkLuggage().then(data => {
console.log(data)
callForCar();
});
這個方法常使用在不確定陣列中(如同範例的 todos)有多少個項目,直接透過迴圈的方式紀錄所有 promise 事件。當其中一個為失敗的話,也可以使用 catch 來做取得錯誤後的處理。這部分就和一開始的 Promise 基礎範例是一樣的道理~
小結
透過 Promise 就可以確保事件完成後才觸發後面要執行的事項。
就不會發生行李還沒整理好,車子就來了的情形啦!