用範例理解 JS Promise

用範例理解 JS Promise

Promise 的好用之處在於,可以確保事件完成後再執行後面的行為,也解決了傳統 callback 波動拳的問題。它用 resolve, reject 來傳遞函式執行後為成功或是失敗的訊息,再用 then 與 catch 來做對應處理。這一篇就用範例快速了解一下 Promise 怎麼用吧!

情境舉例:
當我要去旅遊,首先必須先整理行李後才能出發,
因此行李整理完成,我才會叫車

Promise 基礎範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function checkLuggage() {
return new Promise((resolve, reject) => {
if (parseInt(Math.random() * 2)) { // 隨機
setTimeout(resolve, 10000 * Math.random(), '收好行李');
// 隨機時間(不知道要收多久的概念)
} else {
reject('想慢慢收')
}
})
}
checkLuggage().then((data)=> {
console.log(data, '可以叫車了!');
}).catch((err)=> {
console.log(err, '先不要叫車')
});

迴圈與 Promise, Promise.all 的運用

Promise.all() 這個方法可以同時執行很多 Promise,並在全部都執行完後回傳。

情境舉例
繼續上一個情境,整理行李要拿的東西實在太多
假設我只要發送指令,就可以讓機器人自動去幫我做拿好(做夢
那整理行李這件事,我就可以個別發送『拿衣服』、『拿褲子』、『拿襪子』指令,讓他們去拿 XD
當我發送出指令的時候,我總要知道他們哪時候完成,才方便我打電話叫車嘛~
此時就可以用 promise.all 來確定事情完成:

  1. 先制定好去拿的這個事件,並在完成拿取時回報完成

    1
    2
    3
    4
    5
    6
    let todos = ['拿衣服', '拿褲子', '拿襪子'];
    function getThing(todo) { // 拿東西都是相同指令,就用同一個函式就可以了
    return new Promise((resolve, reject) => {
    setTimeout(resolve, 10000 * Math.random(), todo+'完成');
    })
    }
  2. 接著用 checkLuggage 來統一發送與接受完成的回傳:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function 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);
    })
    });
    }
  3. 最後執行 checkLuggage 函式,等到全部事情都完成了才會執行 callForCar 函式

    1
    2
    3
    4
    5
    6
    7
    function callForCar() {
    console.log('叫車')
    }
    checkLuggage().then(data => {
    console.log(data)
    callForCar();
    });

這個方法常使用在不確定陣列中(如同範例的 todos)有多少個項目,直接透過迴圈的方式紀錄所有 promise 事件。當其中一個為失敗的話,也可以使用 catch 來做取得錯誤後的處理。這部分就和一開始的 Promise 基礎範例是一樣的道理~

小結

透過 Promise 就可以確保事件完成後才觸發後面要執行的事項。
就不會發生行李還沒整理好,車子就來了的情形啦!

評論

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×