延續上一篇使用的程式碼,並在修改函式的 resolve
的結果,會帶出參數的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function promiseFn(num) { return new Promise((resolve, reject) => { setTimeout(() => { if (num) { resolve(`success ${num}`); } else { reject("error"); } }, 0); }); }
promiseFn(1) .then((res) => { console.log(res); }) .catch((rej) => { console.log(rej); });
|
Promise Chain
倘若要在原本的 promise
再做一個 promise
,就會在第一個 then()
中, return
第二個 promiseFn(params)
,並且在後面直接再加一個 then()
來接收新的 promiseFn(params)
函式的結果。
1 2 3 4 5 6 7 8 9 10 11
| promiseFn(1) .then((res) => { console.log(res); return promiseFn(2); }) .then((res) => { console.log(res); }) .catch((rej) => { console.log(rej); });
|
倘若中間有一個參數非真值的話,就會直接跳到 catch()
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| promiseFn(1) .then((res) => { console.log(res); return promiseFn(0); }) .then((res) => { console.log(res); return promiseFn(3); }) .then((res) => { console.log(res); }) .catch((rej) => { console.log(rej); });
|
如果在 catch()
之後想要再進行新的 promise
是可以的,前面結果失敗後,會重啟一個新的 promise
,如下方程式碼,會在失敗後繼續執行 promiseFn(4)
的結果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| promiseFn(1) .then((res) => { console.log(res); return promiseFn(0); }) .then((res) => { console.log(res); return promiseFn(3); }) .then((res) => { console.log(res); }) .catch((rej) => { console.log(rej); return promiseFn(4); }) .then((res) => { console.log(res); });
|
CodePen: https://codepen.io/hnzxewqw/pen/ExKBVJr?editors=1111
then() 也可接收錯誤資料
前面提到大部分 then()
是用來接收成功的結果,但其實也可以接收錯誤的結果,程式碼可以這樣寫:
1 2 3 4 5 6 7 8
| promiseFn(0).then( (res) => { console.log("成功", res); }, (rej) => { console.log("失敗", rej); } );
|
試著將 CodePen 中的參數改成真值或 0,就會在 console
中個別出現要接收的結果,這樣就可以直接使用 then()
來取得結果,就不用使用 catch()
了。
CodePen: https://codepen.io/hnzxewqw/pen/Rwazrba?editors=1111
Promise 常用方法
這兩個方法使用上有點像,只是取值的方式不同。
Promise.all()
全部同時執行,並且只要有一個是錯誤的,就會直接回傳錯誤給 catch
接收。
改寫原本的 promiseFn
函式,多加一個 time
的參數,若沒有傳值進去,預設就是 500 毫秒。
1 2 3 4 5 6 7 8 9 10 11
| function promiseFn(num, time = 500) { return new Promise((resolve, reject) => { setTimeout(() => { if (num) { resolve(`success ${num}`); } else { reject("error"); } }, time); }); }
|
使用 Promise.all()
的方法,取得三次函式執行的結果。
1 2 3 4 5 6 7
| Promise.all([promiseFn(1), promiseFn(2, 1000), promiseFn(3, 2000)]) .then((res) => { console.log(res[0], res[1], res[2]); }) .catch((rej) => { console.log(rej); });
|
將 2 改成 0,就會直接變成接收失敗的結果。
CodePen: https://codepen.io/hnzxewqw/pen/OJNeMmx?editors=1111
Promise.race()
全部同時執行,但只針對第一個回傳的值做為接收值,若第二或第三個有錯誤,則不影響回傳的結果。
將 all()
的方法改成 race()
,並將回傳的結果稍微改寫。
1 2 3 4 5 6 7 8 9 10 11
| Promise.race([ promiseFn(1, 500), promiseFn(2, 300), promiseFn(3, 2000), ]) .then((res) => { console.log(res); }) .catch((rej) => { console.log(rej); });
|
就算把 1 改成 0,也因為第二個執行時間比較早,所以第一個雖然值改成 0,也不會影響結果。
CodePen: https://codepen.io/hnzxewqw/pen/wvGLMqp?editors=1111