防止"未捕获(承诺)"警告。如何避免'catch'堵塞?ES6 承诺与 Q 承诺



我的问题由两部分组成:

第1部分

根据标准ES6Promise,我看到我被迫在任何地方使用catch块,但它看起来像是复制/粘贴,看起来很奇怪。

示例:

我有一些类向后端发出请求(我们称之为API类(。

我对API类使用有一些要求

1(我需要在应用程序的不同部分发出请求,单个请求错误处理:

// somewhere...
api.getUser().then(... some logic ...);
// somewhere in another module and in another part of app...
api.getUser().then(... some another logic...); 

2(我希望"then"块只有在"getUsers"成功时才能工作。

3(我不想在使用api.getUsers()的任何地方写入catch

api.getUser()
// I don't want following
.catch(e => {
showAlert('request failed');
})

因此,我试图在类内为所有"用户请求"实现单一错误处理

class API {
getUser() {
let promise = makeRequestToGetUser();
promise.catch(e => {
showAlert('request failed');
});
return promise;
}
}

但如果请求失败,我仍然被迫使用catch

api.getUser()
.then(... some logic...)
.catch(() => {}) // <- I forced to write it to avoid of “Uncaught (in promise)” warning

否则,我将在控制台中收到"Uncaught(in promise("警告。所以我不知道在我使用api实例的任何地方如何避免.catch块。

似乎这是由于在这样的代码中抛出错误:

// This cause "Uncaught error"
Promise.reject('some value').then(() => {});

也许你可以说"只要回到你的课堂上"兑现"承诺"。

class API {
getUser() {
return makeRequestToGetUser().catch(e => {
showAlert('request failed');
return ... 
});
}
}

但这与我的#2要求相矛盾。

请参阅此演示:https://stackblitz.com/edit/promises-catch-block-question

所以我的第一个问题是如何在不在我使用api调用的任何地方写入catch块的情况下实现所描述的逻辑

第2部分

我检查了具有Q库的相同API类实现是否会得到相同的结果,并感到惊讶,因为我没有得到“Uncaught (in promise)” warning。顺便说一句,这比原生ES6 Promises的行为更令人期待。

在此页面中https://promisesaplus.com/implementations我发现Q库是Promises/A+规范的实现。但为什么它有不同的行为?es6 promise是否尊重Promises/A+规范?

有人能解释为什么这些库有不同的行为,哪一个是正确的,以及在"ES6-Promises实现"正确的情况下如何实现所提到的逻辑吗?

我看到我被迫在的所有地方使用catch块

不,你不需要这么做。相反,then创建的promise返回给调用者(以及该调用者的调用者,以及…(。在最高层处理错误(例如,启动调用序列的事件处理程序(。

如果对您来说catch仍然太多,您可以挂接unhandledrejection事件并阻止其默认值:

window.addEventListener('unhandledrejection', event => {
event.preventDefault();
// You can use `event.reason` here for the rejection reason, and
// `event.promise` for the promise that was rejected
console.log(`Suppressed the rejection '${event.reason.message}'`);
});
Promise.reject(new Error("Something went wrong"));

浏览器将在控制台中报告未处理的拒绝之前触发该事件。

Node.js也支持这一点,在process对象上:

process.on('unhandledRejection', error => {
// `error` is the rejection reason
});

请注意,您可以直接获得原因,而不是作为事件对象的属性。

所以我不知道如何在我使用api实例的任何地方避免.catch块。

getUser的调用者肯定需要知道它失败了吗?我的意思是,如果答案真的是"不,他们不",那么事件就是前进的道路,但实际上使用api的代码应该是这样的:

function useTheAPI() {
return getUser()
.then(user => {
// Do something with user
});
}

(或等效的async(,使得调用useTheAPI的代码知道发生了错误;同样,只有顶层才需要实际处理错误。

有人能解释为什么这些库有不同的行为,哪一个是正确的,以及在"ES6-Promises implementation"正确的情况下如何实现上述逻辑吗?

两者都是正确的。完全在userland(图书馆所在地(报告未处理的异常是很难做到的,甚至是不可能做到的,这样就不会出现误报。JavaScript引擎可以将其作为垃圾收集的一部分来执行(例如:如果没有任何内容再引用promise,并且它被拒绝,并且没有任何内容处理该拒绝,则发出警告(。

相关内容

  • 没有找到相关文章

最新更新