昨日講完了 Promise
的特性與基本用法,今日再來討論更深入的應用。
首先就是剩下的兩個方法: Promise.all
、Promise.race
。
Promise.all
能夠將傳入的多個 Promise
同時執行(平行處理),並且等到所有傳入的 Promise
都回應狀態後,才會進入 then
,而 then
中的 resolve function
傳入的參數即為一開始傳入的所有 Pormise
的 resolve
回傳值。
這邊一樣呼叫昨天網美小花的例子,
var willTogether = function(money) {
return new Promise(function (resolve, reject) {
if(money > 100) {
resolve("我愛你 " + money + " 元先生");
} else {
reject(new Error('你是一個好人,但你值得更好的人'));
}
});
}
我們昨天的範例是一次只有一位追求者,所以 300
元先生必須等到網美小花回應 200
元先生後,才能進行追求,
willTogether(200)
.then(function(val) {
// 當網美小花回應 Mr.200 後
// Mr.300 接著追求
return willTogether(300);
})
.then(function(val) {
// 網美小花回應 Mr.300
})
.catch(function(err) {
console.log(err);
});
現實生活中有這種事情,追求者會輪流排隊嗎?
好人卡多到可以打牌的小王覺得不行!
為了更貼近真實案例,所有追求者應該是同時追求,但是還是為了公平,所以會等到網美小花回應所有追求者後,再由他統一公布所有追求者的結果。
而好人小王就是 Promise.all
,程式碼可以寫成這樣,
Promise.all([willTogether(200), willTogether(300)])
.then(function(val) {
console.log(val);
// ["我愛你 200 元先生", "我愛你 300 元先生"]
})
因為傳入多個 Promise
,所有結果會存到一個陣列中。
好人小王覺得自己提供追求者更多機會,網美小花也同時有了多個男友,可喜可賀、可喜可賀。
Promise.all
:
Promise
同時執行。Promise
回傳狀態後,才會接著進行下一步。then
的 resolve function
將會收到所有 Promise
回傳的結果。但是使用上要非常注意,因為只要傳入的 Promise
中有一個 reject
,將會導致直接進入 catch
,也不會收到其他 resolve
狀態的回傳值。
像是這樣,就算 willTogether(200)
的狀態應該會是 resolve
,但是 willTogether(50)
的 reject
導致直接進入 catch
,then
中也不會印出 Mr.200。
Promise.all([willTogether(200), willTogether(50)])
.then(function(val) {
console.log(val); // 不會顯示出 Mr.200
})
.catch(function(err) {
console.log(err); // sorry
})
簡單來講,就是只要有一個失敗,其他人也涼啦!
上方都理解後,Promise.race
也差不多理解了,它和 Promise.all
的差別在於,Promise.race
只要有一個完成,就會進入 then
,不會等剩下的 Promise
。
我們把程式碼改一下,讓網美小花的變成來者不拒,但是考慮時間變成隨機(0~3秒),
順便也把函數改成箭頭函式
的寫法:
var willTogether = (name) => {
return new Promise((resolve, reject) => {
var s = Math.floor(Math.random() * 4);
setTimeout(() => resolve("恭喜你: " + name), s * 1000);
});
}
忘記
箭頭函式
的可以到 Day6 複習。
接下來就是有多個競爭者同時追求,看誰最幸運,第一個被網美小花回應!
Promise.race([willTogether("Bob"), willTogether("Tom"), willTogether("Ken")])
.then(function(val) {
console.log(val); // 顯示第一個完成的
})
.catch(function(err) {
console.log(err);
})
執行結果(每次都不一樣)
至此 Promise
的四個方法都已講完
Promise.resolve
Promise.reject
Promise.all
Promise.race
下一篇會介紹被譽為處理非同步的最佳方案: await
、async
。
今日的分享就到這,我們明天見