Promise 有 Fulfilled Promise 與 Rejected Promise 兩種,其中 Fulfilled Promise 可由 Promise.resolve()
建立;而 Rejected Promise 則須由 Promise.reject()
或 Throw
建立。
Version
macOS Mojave 10.14.6
VS Code 1.38.1
Quokka 1.0.250
ECMAScript 2018
Promise.reject()
let fetchData = () => Promise.resolve('Hello World');
fetchData().then(x => {
console.log(x);
return Promise.reject(new Error('Something wrong'));
}).catch(e => console.log(e.message));
若想在 fulfilled handler 內自行建立 rejected promise,可先建立 Error
object,再由 Promise.reject()
包成 rejected promise。
由於 catch()
callback 中的 e
為 Error
object,必須使用 e.message
才能取得 Something wrong
。
Throw
let fetchData = async () => 'Hello World';
fetchData().then(x => {
console.log(x);
throw new Error('Something wrong');
}).catch(e => console.log(e.message));
也可在 fulfilled handler 中直接使用 throw
建立 rejected promise,其中 throw
就是 Promise.reject()
的 syntatic sugar。
Try Catch
let fetchData = async () => 'Hello World';
try {
let x = await fetchData();
console.log(x);
throw new Error('Something wrong');
} catch(e) {
console.log(e.message);
}
throw
除了能用在 fulfilled handler 外,也能用在 try catch
block 中,如此更符合 imperative 與 synchronous 習慣。
但別忘了 throw
是 syntatic sugar,當 throw
搭配 await
時,它產生的是包裹 Error
object 的 rejected promise。
String or Error Object ?
let fetchData = () => Promise.resolve('Hello World');
fetchData().then(x => {
console.log(x);
return Promise.reject('Something wrong');
}).catch(e => console.log(e));
以語法而言,我們的確能將 string 傳給 Promise.reject()
,如此將回傳包裹 string 的 rejected promise, catch()
callback 的 e
就可直接抓到 Something wrong
。
不過 Error
object 畢竟有完整的 stack trace 可用,對於 debug 有幫助。
MDN 也是建議產生 Error
object 的 rejected promise。
Conclusion
Promise.reject()
為標準產生 rejected promise 方式throw
為Promise.reject()
的 syntatic sugar,尤其放在try catch
block 很方便,但別忘了它本質仍是包裹Error
object 的 rejected promise- Rejected promise 也可直接包裹 string 即可,但不像
Error
object 有完整 stack trace,實務上建議使用Error
object 的 rejected promise
Reference
Marius Schulz, Create a Rejected Promise in JavaScript
MDN, Promise.reject()