What is Promise ?
- Promise 是一個強大的異步執行流程語法結構
- 並非所有的 Callback 都是異步執行, 使用者自己設計的 Callback 結構當然也非異步, 但可透過一些 API讓使用者設計的 Callback 變成異步, 像是 :
- 使用計時器(timer)函式: setTimeout, setInterval
- 特殊的函式: nextTick, setImmediate
Why Promise ?
- 在執行 Async 事情當錯誤發生時, 可以透過 reject
拋出例外
進行對應處理 - 強大的
chaining
能力(thenable)
How to use Promise ?
1 | function Asyncfunc(){ |
About .then(…) / .catch(…)
.then(onFullFill)
- .then() 本身會回傳一個
新的promise
=> 造就了 chainable 的能力 - onFullFill
- 第一個參數為上一個 promise resolve(or onFullFill) function 的回傳值
- 可以回傳三種東西
- 值 (string, number … etc.)
- Promise => 會成為這個 .then() 回傳的 Promise
- thenable object
- 當 .then() 的第一個參數不是 function 時且 fullfill時, 會忽略這個 .then() (也就是有寫這個 .then() 等於沒寫)
.catch(onReject)
- 其實就只是 .then(undefined, onReject) 的語法糖而已 (因此特性同上)
1 | function doSomething1() { |
1 | // Result |
Promise.race()
- 一群 Promise 比賽, 只回傳
第一個
完成的 Promise
1 | let racePromise = function(id,timer) { |
Promise.all() - Parallel 執行
- 一次 Run 一群 Promise, 待
全部都完成
, 回傳一個存放所有完成結果的陣列 若其中只要有
一個Promise reject
, 就會算全部失敗
, 執行 reject 部分1
2
3
4
5
6
7
8
9
10
11
12
13let racePromise = function(id,timer) {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve(`${id} is Complete!`);
}, timer);
});
}
Promise.all([racePromise("01", 1000), racePromise("02", 2000)])
.then((data) => {
console.log(data);
// Output : ["01 is Complete!", "02 is Complete!"] (兩秒後才會得到此Output, 因為需等所有Promise完成)
})允許部分成功
1
2
3
4
5
6
7...
const data = await Promise.all(
[S_FakeAPICall2s(), S_FakeAPICall1s(), F_FakeAPICall1s()].map(p =>
p.catch(e => "FAILED!")
)
);
...- 失敗的 Promise (F_FakeAPICall1s()) 會被 chain map 的 catch 接住, 回傳 “FAILED!”, 因此外層 data 仍可已得到一個結果陣列 .
一些觀念
- .then() 會 return 一個
新
的 Promise 物件, 因此可以 chaining - onFullfilled (a.k.a resolve) 可以有三種回傳值
- value(回隨著新的Promise物件傳下去)
- Promise物件
- thenable物件