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 catchblock 很方便,但別忘了它本質仍是包裹Errorobject 的 rejected promise- Rejected promise 也可直接包裹 string 即可,但不像
Errorobject 有完整 stack trace,實務上建議使用Errorobject 的 rejected promise
Reference
Marius Schulz, Create a Rejected Promise in JavaScript
MDN, Promise.reject()