Promise
UnhandledPromiseRejectionWarning
如果 Promise 运行过程中抛出错误,或者状态变为rejected
,但是没有相应的处理代码,那么 Node 会抛出一个警告UnhandledPromiseRejectionWarning
。
new Promise(function (resolve, reject) {
reject('message');
console.log('hello');
})
// hello
// UnhandledPromiseRejectionWarning: message
上面代码中,Promise 变为rejected
状态,但是没有处理的代码,导致抛出警告UnhandledPromiseRejectionWarning
。由于抛出的是警告,而不是错误,所以不影响hello
的输出。请跟下面的代码比较一下。
new Promise(function (resolve, reject) {
throw new Error('message');
console.log('hello');
})
// UnhandledPromiseRejectionWarning: Error: message
上面代码中,Promise 内部抛出错误,没有得到处理,所以会有警告UnhandledPromiseRejectionWarning
。Promise 内部的错误阻止 Promise 内部的代码继续向下运行,所以不会输出hello
。
消除这个警告的方法很简单,就是为 Promise 加上错误处理代码,即catch
代码块。
new Promise(function (resolve, reject) {
reject('message');
console.log('hello');
}).catch(function (err) { console.log (err) })
// hello
// message
上面代码中,由于catch
代码块的存在,所以不会抛出警告。
async 函数里面使用 Promise,也要放在try/catch
代码块之中。
const p = new Promise(function (resolve, reject) {
reject('message');
});
(async function () {
try {
await p;
} catch (err) {
console.log(err);
}
})();
// message
上面代码中,如果 Promise 没有放在try/catch
代码块,就会抛出警告UnhandledPromiseRejectionWarning
。
Node 还提供process
对象的unhandledRejection
事件,在抛出警告UnhandledPromiseRejectionWarning
之前,就会触发这个事件。如果设置了这个事件的处理代码,就不会抛出警告UnhandledPromiseRejectionWarning
。
new Promise(function (resolve, reject) {
reject('message');
});
process.on('unhandledRejection', function (err) {
console.log(err);
});
// message
Node 开发团队打算废除UnhandledPromiseRejectionWarning
,以后如果没有相应的处理代码,Promise 内部抛错或者变为rejected
状态,会导致 Node 进程终止执行,并且有一个非零的返回码。所以应该养成习惯,只要有 Promise,就要部署失败情况下的代码。