Promise reject() 导致 "Uncaught (in promise)" 警告
Promise reject() causes "Uncaught (in promise)" warning
一旦调用了 promise reject()
回调,"Uncaught (in promise)" 就会在 Chrome 控制台中显示一条警告消息。我无法理解它背后的原因,也无法摆脱它。
var p = new Promise((resolve, reject) => {
setTimeout(() => {
var isItFulfilled = false
isItFulfilled ? resolve('!Resolved') : reject('!Rejected')
}, 1000)
})
p.then(result => console.log(result))
p.catch(error => console.log(error))
警告:
编辑:
我发现如果 onRejected
处理程序没有显式提供给 .then(onResolved, onRejected)
方法,JS 会自动提供一个隐式处理程序。它看起来像这样:(err) => throw err
。自动生成的处理程序将依次抛出。
参考:
If IsCallable(onRejected)` is false, then
Let onRejected be "Thrower".
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performpromisethen
发生这种情况是因为您没有将捕获处理程序附加到第一个 then
方法返回的承诺,因此当承诺拒绝时,该方法没有处理程序。您 do 有一个用于最后一行中的承诺 p
,但没有用于由 [=11 返回的 chained 承诺=] 方法,在它之前的行中。
正如您在下面的评论中正确添加的那样,当未提供捕获处理程序(或它不是函数)时,default one will throw 错误。在承诺链中,可以使用 catch
方法回调捕获此错误,但如果存在 none,则 JavaScript 引擎将像处理任何其他未捕获的错误一样处理该错误,并在这种情况下应用默认处理程序,这会导致您在控制台中看到输出。
为避免这种情况,将 .catch
方法链接到第一个 then
返回的承诺,如下所示:
p.then( result => console.log('Fulfilled'))
.catch( error => console.log(error) );
即使您正确使用 Promises:p.then(p1).catch(p2)
如果您的 p2 函数最终抛出一个您打算使用 window.onerror 之类的机制捕获的异常,您仍然可以获得未捕获的异常。原因是堆栈已经被 promise 中完成的错误处理解开。要解决此问题,请确保您的错误代码(由拒绝函数调用)不会引发异常。它应该只是 return.
如果错误处理代码可以检测到堆栈已经展开(这样您的错误调用就不必为这种情况设置标志),并且如果有人知道如何轻松地做到这一点,那就太好了我将编辑此答案以包含该解释。
我已经在我的项目中解决了这个问题,它是一个大型企业项目。我组懒得写空catch几百遍了
Promise.prototype.then = function (onFulfilled, onRejected) {
return baseThen.call(this, (x: any) => {
if (onFulfilled)
onFulfilled(x);
}, (x: any) => {
if (onRejected)
onRejected(x);
});
};
此代码不会导致“未捕获承诺”异常:
// Called from top level code;
// implicitly returns a Promise
testRejectCatch = async function() {
// Nested within testRejectCatch;
// simply rejects immediately
let testReject = function() {
return new Promise(function(resolve, reject) {
reject('test the reject');
)};
}
//***********************************************
// testRejectCatch entry.
//***********************************************
try {
await testReject(); // implicitly throws reject exception
catch(error) {
// somecode
}
//***********************************************
// top level code
//***********************************************
try{
testRejectCatch() // Promise implicitly returned,
.catch((error) => { // so we can catch
window.alert('Report error: ' + error);
// must not throw error;
});
}
catch(error) {
// some code
}
说明:
首先,有一个术语问题。 “捕获”一词是
以两种方式使用:在 try-catches 和 Promises 中。
所以,很容易对“throw”感到困惑;是投掷吗
尝试成功还是承诺成功?
答案:testReject 中的 reject 是抛给 Promise 的
隐式捕获,等待 testReject;然后扔到
testRejectCatch() 处的 .catch。
在此上下文中,try-catch 无关紧要并被忽略;
投掷与他们无关。
testRejectCatch处的.catch满足要求
原来的投掷必须在某个地方被抓住,
所以你不会遭受“未被承诺......”的例外。
要点:Promises 的抛出是 .catch 的抛出,
不要尝试捕捉;并且必须在一些 .catch
中处理
编辑:
在上面的代码中,拒绝通过 .catches 向上传播。
如果需要,您可以转换为传播 try-catches。
在第 17 行,将代码更改为:
let bad = '';
await testReject().catch((error) => {bad = error});
if (bad) throw bad;
现在,您已切换到 try-catch。
我运行进入这个问题,但是没有setTimeout()
.
以防其他人遇到此问题:如果在 Promise 构造函数中您只是同步调用 reject()
,那么添加多少 .then()
和 .catch()
处理程序都没有关系对于返回的 Promise,它们不会阻止未捕获的 promise 拒绝,因为 promise 拒绝会在你之前发生
一旦调用了 promise reject()
回调,"Uncaught (in promise)" 就会在 Chrome 控制台中显示一条警告消息。我无法理解它背后的原因,也无法摆脱它。
var p = new Promise((resolve, reject) => {
setTimeout(() => {
var isItFulfilled = false
isItFulfilled ? resolve('!Resolved') : reject('!Rejected')
}, 1000)
})
p.then(result => console.log(result))
p.catch(error => console.log(error))
警告:
编辑:
我发现如果 onRejected
处理程序没有显式提供给 .then(onResolved, onRejected)
方法,JS 会自动提供一个隐式处理程序。它看起来像这样:(err) => throw err
。自动生成的处理程序将依次抛出。
参考:
If IsCallable(onRejected)` is false, then
Let onRejected be "Thrower".
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performpromisethen
发生这种情况是因为您没有将捕获处理程序附加到第一个 then
方法返回的承诺,因此当承诺拒绝时,该方法没有处理程序。您 do 有一个用于最后一行中的承诺 p
,但没有用于由 [=11 返回的 chained 承诺=] 方法,在它之前的行中。
正如您在下面的评论中正确添加的那样,当未提供捕获处理程序(或它不是函数)时,default one will throw 错误。在承诺链中,可以使用 catch
方法回调捕获此错误,但如果存在 none,则 JavaScript 引擎将像处理任何其他未捕获的错误一样处理该错误,并在这种情况下应用默认处理程序,这会导致您在控制台中看到输出。
为避免这种情况,将 .catch
方法链接到第一个 then
返回的承诺,如下所示:
p.then( result => console.log('Fulfilled'))
.catch( error => console.log(error) );
即使您正确使用 Promises:p.then(p1).catch(p2)
如果您的 p2 函数最终抛出一个您打算使用 window.onerror 之类的机制捕获的异常,您仍然可以获得未捕获的异常。原因是堆栈已经被 promise 中完成的错误处理解开。要解决此问题,请确保您的错误代码(由拒绝函数调用)不会引发异常。它应该只是 return.
如果错误处理代码可以检测到堆栈已经展开(这样您的错误调用就不必为这种情况设置标志),并且如果有人知道如何轻松地做到这一点,那就太好了我将编辑此答案以包含该解释。
我已经在我的项目中解决了这个问题,它是一个大型企业项目。我组懒得写空catch几百遍了
Promise.prototype.then = function (onFulfilled, onRejected) {
return baseThen.call(this, (x: any) => {
if (onFulfilled)
onFulfilled(x);
}, (x: any) => {
if (onRejected)
onRejected(x);
});
};
此代码不会导致“未捕获承诺”异常:
// Called from top level code;
// implicitly returns a Promise
testRejectCatch = async function() {
// Nested within testRejectCatch;
// simply rejects immediately
let testReject = function() {
return new Promise(function(resolve, reject) {
reject('test the reject');
)};
}
//***********************************************
// testRejectCatch entry.
//***********************************************
try {
await testReject(); // implicitly throws reject exception
catch(error) {
// somecode
}
//***********************************************
// top level code
//***********************************************
try{
testRejectCatch() // Promise implicitly returned,
.catch((error) => { // so we can catch
window.alert('Report error: ' + error);
// must not throw error;
});
}
catch(error) {
// some code
}
说明: 首先,有一个术语问题。 “捕获”一词是 以两种方式使用:在 try-catches 和 Promises 中。 所以,很容易对“throw”感到困惑;是投掷吗 尝试成功还是承诺成功?
答案:testReject 中的 reject 是抛给 Promise 的 隐式捕获,等待 testReject;然后扔到 testRejectCatch() 处的 .catch。
在此上下文中,try-catch 无关紧要并被忽略; 投掷与他们无关。
testRejectCatch处的.catch满足要求 原来的投掷必须在某个地方被抓住, 所以你不会遭受“未被承诺......”的例外。
要点:Promises 的抛出是 .catch 的抛出, 不要尝试捕捉;并且必须在一些 .catch
中处理编辑: 在上面的代码中,拒绝通过 .catches 向上传播。 如果需要,您可以转换为传播 try-catches。 在第 17 行,将代码更改为:
let bad = '';
await testReject().catch((error) => {bad = error});
if (bad) throw bad;
现在,您已切换到 try-catch。
我运行进入这个问题,但是没有setTimeout()
.
以防其他人遇到此问题:如果在 Promise 构造函数中您只是同步调用 reject()
,那么添加多少 .then()
和 .catch()
处理程序都没有关系对于返回的 Promise,它们不会阻止未捕获的 promise 拒绝,因为 promise 拒绝会在你之前发生