这显然是一个SSCCE。我有以下(jsFiddle here):
<html>
<body>
<input id='file-dlg' type='file'/>
<br/>
<button id='submit' type='button'>submit</button>
<script>
document.getElementById('file-dlg').addEventListener('change', storeAPromise);
var p;
function storeAPromise() {
p = new Promise(function executor(resolve, reject) {
try {
throw new Error('snafu');
} catch(e) {
reject(e);
}
});
};
document.getElementById('submit').onclick = function() {
p.then(function() {}, function reject(e) {
console.error('some problem happenned', e);
});
};
</script>
</body>
</html>
当用户使用文件对话框选择文件时,我希望在控制台上打印任何内容,因为Error
被捕获并且承诺的reject
功能是调用。相反,我希望错误出现在控制台上,并带有描述&#34;发生了一些错误&#34;只有当我点击&#34;提交&#34;按钮。
然而,这不是我观察到的。一旦用户选择了我在控制台上看到的对话框的文件:
Uncaught (in promise) Error: snafu(…)
当用户按下&#34;提交&#34;按钮我确实看到了预期的日志行&#34;发生了一些问题&#34;但是我不明白为什么我也看到了早期的&#34; Uncaught(in promise)&#34;用户使用文件对话框选择文件时的日志行。我也不明白为什么错误被描述为&#34; Uncaught&#34;鉴于我(无条件地)捕获所有异常并且简单地调用reject
函数。
答案 0 :(得分:6)
它不是未被捕获的例外,它是未被捕获的拒绝。承诺不应该在被拒绝状态下悬挂而没有附加错误回调 - 这就是控制台警告你的原因。您还可以使用unhandledrejection
event在您的应用程序中处理这些案例。
如果您想稍后处理错误(在用户单击按钮时安装处理程序,可能永远不会!),您仍需要立即安装空回调(明确忽略错误)以禁止警告
var p = Promise.resolve();
document.getElementById('file-dlg').addEventListener('change', function createPromise() {
p = new Promise(function executor(resolve, reject) {
throw new Error('snafu');
});
p.catch(e => {/* ignore for now */});
});
document.getElementById('submit').addEventListener('click', function addErrorHandler() {
p.catch(function onReject(e) {
console.error('some problem happened', e);
});
});
请注意,您不需要try
/ catch
- 承诺构造函数默认情况下会捕获执行程序中的所有异常。