Promise - 處理同步、非同步事件 - 2 - all、race 與 chain 鏈結

上一篇(參考這邊)我們已經學習到如何簡單的建立 promise 物件來處理非同步、同步事件。但若我們想要傳入一些參數給 Promise 使用該怎麼辦呢?

傳入參數給 Promise 使用

Promise 流程圖
其實作法很簡單,我們只要建立一個 function 來包原本的 Promise 物件即可,以下我們同樣用跑步的範例來實作。
我們先建立一個 function,並傳入一個參數someone,來指定誰要跑步(也可重複使用 Promise 指定不同跑者),寫入隨機產生是否要跑步及跑步秒數的變數,然後我們需要 return 一個透過建構式建立的 Promise,接下來就跟原本的建立方式差不多,利用 resolve() 及 reject() 來傳遞訊息,也可使用傳入的someone變數來指定跑者,最後使用 then()catch()來接收訊息。

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
// 這次為了從外部引入資料,所以先建立 function 再 return Promise 物件
let running = someone => {
let run = Math.floor(Math.random() * 2); // 隨機產生 0 或 1
let duration = Math.floor(Math.random() * 10) + 1; // 隨機產生 0 ~ 10
console.log(
someone + ' ' + '考慮是否要跑步:' + run,
'預計跑步秒數:' + duration
);
// 建立 Promise 物件
return new Promise((resolve, reject) => {
if (run) {
window.setTimeout(() => {
resolve(someone + ' 跑了 ' + duration + ' 秒');
}, duration * 1000);
} else {
reject(someone + ' 不想跑了');
}
});
};
running('ASin')
.then(data => {
console.log(data);
})
.catch(data => {
console.log(data);
});

Promise 外部帶入參數實作

Promise.all( )、Promise.race( ) 傳入多個 Promise 事件

有時候一個人跑步很無聊想找人陪伴,若是多個人跑步時那要怎麼操作呢?
此時我們有兩種方法可以一次傳入多個 Promise 事件:

  • all同時執行多個 Promise 事件,在全部完成後統一將訊息以陣列回傳
  • race同時執行多個 Promise 事件,這個方法僅會回傳第一個完成的訊息

以下我們同樣用上面範例的 Promise 物件來實作多個 Promise 事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let running = someone => {
let run = Math.floor(Math.random() * 2);
let duration = Math.floor(Math.random() * 10) + 1;
console.log(
someone + ' ' + '考慮是否要跑步:' + run,
'預計跑步秒數:' + duration
);
return new Promise((resolve, reject) => {
if (run) {
window.setTimeout(() => {
resolve(someone + ' 跑了 ' + duration + ' 秒');
}, duration * 1000);
} else {
reject(someone + ' 不想跑了');
}
});
};
running('ASin')
.then(data => {
console.log(data);
})
.catch(data => {
console.log(data);
});

all

使用 Promise.all( ) 並以陣列的方式傳入多個 Promise 物件,這邊傳入 ASin 及 Hyh 兩個 Promise,結果可以發現,這個方法會在全部完成後統一回傳陣列,而這個陣列的內容也是 promise 中 resolve 的內容。不過只要其中一個沒完成就會直接回傳 reject。

1
2
3
4
5
6
7
Promise.all([running('ASin'), running('Hyh')])
.then(data => {
console.log(data);
})
.catch(data => {
console.log(data);
});

Promise.all()

race

使用 Promise.race( ) 並以陣列的方式傳入多個 Promise 物件,這邊傳入 ASin 及 Hyh 兩個 Promise,而這個方法只會回傳第一個完成的事件。不過只要其中一個沒完成就會直接回傳 reject。

1
2
3
4
5
6
7
Promise.race([running('ASin'), running('Hyh')])
.then(data => {
console.log(data);
})
.catch(data => {
console.log(data);
});

Promise.race()

Promise Chain 鏈結

若是我們的 Promise 事件執行是有順序之分的,那麼該怎麼辦呢?
當 ASin 跟 Hyh 一起跑步,但 Hyh 想先看 ASin 跑,她才要跑時,我們可以then()來鏈結 Promise 事件。
首先,ASin 是第一個跑的,所以我們先執行 ASin 的跑步 Promise 事件,不同的是我們在 console.log(data)後又 return 了 Hyh 的 Promise 事件,然後我們在後面又用then()來接收 Hyh 的 Promise 事件訊息,也因此我們可以等待 ASin 這邊執行完以後,再來執行 Hyh,用此方法就可以減少 Callback 問題,也可以依序執行不同的 promise 事件

1
2
3
4
5
6
7
8
9
10
11
running('ASin')
.then(data => {
console.log(data);
return running('Hyh');
})
.then(data => {
console.log(data);
})
.catch(data => {
console.log(data);
});

Promise Chain

0%