为什么 Chrome 告诉我我有一个未处理的拒绝,而我明明正在处理它?
Why is Chrome telling me I have an Unhandled Rejection when I clearly am handling it?
我正在为 Javascript 承诺使用 "defer" 模式,让我 return 对调用函数的承诺,然后在稍后的某个时间,在某些情况下,解决或拒绝那个承诺。
正如您在我提供的代码中看到的那样,除了在浏览器中出现 Unhandled Rejection
错误之外,一切都按预期工作。
function promiseGenerator() {
const deferred = {};
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
const generatedPromise = promiseGenerator();
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
});
generatedPromise.promise.then().catch(e => {
console.log("This is the catch", e);
});
generatedPromise.reject("Oh no");
我期待在控制台中看到 This is the catch Oh no
- 我做到了。但为什么我会收到错误消息?很明显,我的拒绝 正在 处理中!
注意 我不想(必然)将捕获链接到 then
因为我可能想在其他地方单独添加这个捕获代码
这是一个 Codesandbox link
https://codesandbox.io/embed/deferred-promise-catch-vanilla-pjor9
为了捕获传递给 new Promise()
构造函数的回调中抛出的错误,需要将 catch
块附加到 .then()
的返回值,而不是承诺本身。
generatedPromise.promise
.then(res => {
console.log("A string deferred resolved!", res);
})
.catch(e => {
console.log("This is the catch", e);
});
generatedPromise.reject
对象是对您传递给构造函数 (resolve, reject) => {}
的回调中的 reject
参数的引用。
同理,generatedPromise.promise
是对 new Promise()
返回对象的引用。
那么唯一可以捕获调用 genetratedPromise.reject()
引发的错误的方法是将 .catch()
链接到 .then()
。没有别的办法了。
这是看待这个问题的另一种方式:
const promise = new Promise((resolve, reject) => {
reject('test')
});
promise.catch(err => 'foo'); // throws unhandled promise rejection. Cause you rejected, but didn't catch it after the .then statement
promise.then(() => {}).catch(err => 'foo'); // doesn't throw rejection
您在承诺链中使用了 catch。
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
}).catch(error => console.log('error));
编辑:有人更快。
Edit2:看到其他 post 的评论。可能有办法,但不是很好的做法。
function promiseGenerator() {
const deferred = {};
//do your function stuff here
try{
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
});
} catch(ex){
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve(ex);
});
}
return deferred;
}
这样一个承诺有两个不同的结果,另一种方法是使用 try catch 块,而不是 if else 语句,但这完全取决于您的应用程序。
Promise 拒绝未在 .then()
回调中处理,当您首先附加 then()
回调并且承诺被拒绝时,错误被视为未处理,因为没有 catch()
在 then()
.
之后
处理这个问题的正确方法是添加一个 catch()
链接到 then()
:
function promiseGenerator() {
const deferred = {};
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
const generatedPromise = promiseGenerator();
//Error from the rejection is handled in the catch
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
}).catch(e => {
console.log("This is the catch", e);
});
generatedPromise.reject("Oh no");
另一种方法是将拒绝处理程序作为 then()
回调的第二个参数传递以处理 Promise 拒绝:
function promiseGenerator() {
const deferred = {};
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
const generatedPromise = promiseGenerator();
//Error from the rejection is handled in the second callback
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
},
err => {
console.log("This is the catch", err);
});
generatedPromise.reject("Oh no");
我正在为 Javascript 承诺使用 "defer" 模式,让我 return 对调用函数的承诺,然后在稍后的某个时间,在某些情况下,解决或拒绝那个承诺。
正如您在我提供的代码中看到的那样,除了在浏览器中出现 Unhandled Rejection
错误之外,一切都按预期工作。
function promiseGenerator() {
const deferred = {};
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
const generatedPromise = promiseGenerator();
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
});
generatedPromise.promise.then().catch(e => {
console.log("This is the catch", e);
});
generatedPromise.reject("Oh no");
我期待在控制台中看到 This is the catch Oh no
- 我做到了。但为什么我会收到错误消息?很明显,我的拒绝 正在 处理中!
注意 我不想(必然)将捕获链接到 then
因为我可能想在其他地方单独添加这个捕获代码
这是一个 Codesandbox link https://codesandbox.io/embed/deferred-promise-catch-vanilla-pjor9
为了捕获传递给 new Promise()
构造函数的回调中抛出的错误,需要将 catch
块附加到 .then()
的返回值,而不是承诺本身。
generatedPromise.promise
.then(res => {
console.log("A string deferred resolved!", res);
})
.catch(e => {
console.log("This is the catch", e);
});
generatedPromise.reject
对象是对您传递给构造函数 (resolve, reject) => {}
的回调中的 reject
参数的引用。
同理,generatedPromise.promise
是对 new Promise()
返回对象的引用。
那么唯一可以捕获调用 genetratedPromise.reject()
引发的错误的方法是将 .catch()
链接到 .then()
。没有别的办法了。
这是看待这个问题的另一种方式:
const promise = new Promise((resolve, reject) => {
reject('test')
});
promise.catch(err => 'foo'); // throws unhandled promise rejection. Cause you rejected, but didn't catch it after the .then statement
promise.then(() => {}).catch(err => 'foo'); // doesn't throw rejection
您在承诺链中使用了 catch。
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
}).catch(error => console.log('error));
编辑:有人更快。
Edit2:看到其他 post 的评论。可能有办法,但不是很好的做法。
function promiseGenerator() {
const deferred = {};
//do your function stuff here
try{
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
});
} catch(ex){
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve(ex);
});
}
return deferred;
}
这样一个承诺有两个不同的结果,另一种方法是使用 try catch 块,而不是 if else 语句,但这完全取决于您的应用程序。
Promise 拒绝未在 .then()
回调中处理,当您首先附加 then()
回调并且承诺被拒绝时,错误被视为未处理,因为没有 catch()
在 then()
.
处理这个问题的正确方法是添加一个 catch()
链接到 then()
:
function promiseGenerator() {
const deferred = {};
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
const generatedPromise = promiseGenerator();
//Error from the rejection is handled in the catch
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
}).catch(e => {
console.log("This is the catch", e);
});
generatedPromise.reject("Oh no");
另一种方法是将拒绝处理程序作为 then()
回调的第二个参数传递以处理 Promise 拒绝:
function promiseGenerator() {
const deferred = {};
const promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
const generatedPromise = promiseGenerator();
//Error from the rejection is handled in the second callback
generatedPromise.promise.then(res => {
console.log("A string deferred resolved!", res);
},
err => {
console.log("This is the catch", err);
});
generatedPromise.reject("Oh no");