[JS] ES6 - Promise (1)

前言

Promise 是 ES6 當中用來解決 christmas callback hell 的一種非同步的處理方式。

Promise 的三種狀態

  • Pending: 初始狀態
  • Fulfill: 成功完成
  • Result: 失敗

Promise 的狀態都是從 pending 開始,一旦 Promise 的狀態被確定(fulfill or result),就不會再改變。

Promise Constructor

  • 要記得處理 error 的部分
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 myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Good to go!');
}, 1000);

setTimeout(() => {
reject('uh oh!');
},500)
});

myPromise.then((res) => {
console.log(res);
}, (err) => {
console.log(err); // uh oh!
})

// 或者使用 catch 處理 error
myPromise
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
})

Promise.all([iterable])

  • 等傳入的所有 Promise都跑完,會回傳一個新的 Promise。
  • 只要有其中一個 Promise reject 就會執行 ㄒerr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Good to go!');
}, 1000);
});

let myPromise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 2 - the promising');
}, 1500);
});

Promise.all([myPromise, myPromise2])
.then((data) => {
console.log(data); // ["Good to go!", "Promise 2 - the promising"]
})
.catch((err) => {
console.log(err);
})

Promise.race([iterable])

  • Promise.all() 非常相像,不同點在於,他僅會回傳第一個完成的 Promise。(不論第一個完成的是 resolve 或 reject)
1
2
3
4
5
6
7
Promise.race([myPromise, myPromise2])
.then((data) => {
console.log(data); // 'Good to go!'
})
.catch((err) => {
console.log(err);
})

fetch

  • 使用 fetch 做異步請求,會回傳一個 Promise。
1
2
3
4
5
6
7
8
9
10
fetch('http://api.icndb.com/jokes/random/10')
.then((res) => {
// res.json() 會回傳另外一個 Promise,回傳一個 json 格式的資料
res.json().then((data) => {
console.log(data);
})
})
.catch((err) => {
console.log(err);
})

小結

第一次接觸到 Promise 的時候,頭上都是問號。多看了好幾篇教學文之後才終於稍微比較瞭解。接下來會再找時間了解 Promise 的其他可以使用的方法,以及研究 async 和 await 如何做到 flow control。

參考資料

Let’s Learn ES6 - Promises
Promise MDN