clearTimeout后出现UnhandledPromiseRejectionWarning

时间:2019-08-14 22:52:05

标签: javascript node.js es6-promise cleartimeout

如果我在拒绝承诺后清除计时器-无论我是否拦截承诺,都将在stdout中收到警告“ UnhandledPromiseRejectionWarning”

已选中:节点v10,节点v12,google-chrome 76

let timer;
const promise = new Promise((resolve, reject) => {
    timer = setTimeout(() => {
        console.log('!timeout');
        reject('timeout error');
    });
}, 100);

promise.then(result => {
    console.log('SUCCESS:', result);
}).catch(error => {
    console.log('!onerror');
    console.error('ERROR:', error);
});

promise.finally(() => {
    console.log('!onfinnaly');
    clearTimeout(timer);
});

console.log('!endcode');

nodejs中的控制台输出:

!endcode
!timeout
!onfinnaly
!onerror
ERROR: timeout error
(node:12697) UnhandledPromiseRejectionWarning: timeout error
(node:12697) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:12697) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

使用google-chrome的控制台输出:

!endcode
!timeout
!onfinnaly
!onerror
ERROR: timeout error
Promise.catch (async)
Uncaught (in promise) timeout error

1 个答案:

答案 0 :(得分:1)

如果您在拒绝的Promise上呼叫Promise#finally,则最终返回的Promise也将被拒绝:

window.addEventListener('unhandledrejection', _ => console.error( 'Unhandled Rejection' ) );

Promise.reject( )
  .finally( _ => _ );

如果您可能最终会在被拒绝的Promise上致电,则仍然需要捕获错误以防止未处理的拒绝:

window.addEventListener('unhandledrejection', _ => console.error( 'Unhandled Rejection' ) );

Promise.reject( 'foobar' )
  .finally( _ => _ )
  .catch( e => console.log( 'Caught: ' + e ) );

如果您在catch之后链接finally,而不是直接在promise上调用它,则不会有未处理的拒绝,因为catch会返回一个将兑现的Promise(除非有新的错误被抛出或从catch回调返回了被拒绝的Promise。