您如何处理无法解决的承诺?
示例:
class Utils {
static async thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(number: number) {
return new Promise((resolve, reject) => {
if(number === 2) {
resolve('ok')
}
})
}
}
console.log(await Utils.thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(2))
// this will print "ok" because 2 is passed and the promise is resolved
console.log(await Utils.thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(5))
// this will crash the program silently
uncaughtException
和unhandledRejection
未兑现承诺时不返回任何内容。在等待中添加try/catch
无效(没有错误)。最后,唯一有效的方法是使用Promise.then
而不是await
。
问题是代码库中充斥着async/await
和有时会解决的Promise(取决于条件)
问题:是否可以添加打字机标记来检测缺少的解析/拒绝?还是自动转换所有async/await
以使用Promise.then
的方式?
使用调试器时,程序在Promise之后停止,并且很难找到哪个函数/诺言缺少解析/拒绝。
重写所有async/await
调用以使用Promise.then
是我的最后选择。
答案 0 :(得分:4)
如果您的承诺偶尔不会解决或拒绝,而这不是他们应有的工作方式(通常不是这样),那么您只需要解决该问题即可。确实没有解决方法。正确的解决方法是降到最低级别并修复代码,以使它每次都能可靠地解决或拒绝。
这不是正确的解决方法,但是实现超时包装可以帮助调试,从而为您提供一条日志消息,其中包含类似于堆栈跟踪的超时承诺:
function rejectT(t) {
// create potential error here for better opportunity at stack trace
let e = new Error("Promise timed out");
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(e);
reject(e);
}, t);
});
}
function timeout(p, t = 5000) {
return Promise.race([p, rejectT(t)]);
}
然后您可以包装任何承诺,而不是:
fn().then(...).catch(...)
您可以使用:
timeout(fn()).then(...).catch(...);
或者,如果您想设置自定义超时值:
timeout(fn(), 1000).then(...).catch(...);
同样,这是调试代码,以帮助找到需要修复的罪魁祸首并帮助测试修复,而不是浪费代码。
重写所有异步/等待调用以使用Promise。那是我的最后选择。
我完全不知道这对您有什么帮助。如果await
从未完成,promise.then()
都不会。在这方面,它们是完全相同的。如果承诺从未解决或拒绝,那么.then()
处理程序也将不会被调用。
问题是代码库中充斥着异步/等待和有时会解决的Promises(取决于条件)
除了有条不紊的代码审查之外,这里没有捷径可走,找到具有可能永远无法解析或拒绝的代码路径的可疑代码,然后构建单元测试以测试在各种情况下返回promise的每个函数。
一个可能无法解决或拒绝的代码源是一些promise反模式。其中一些是反模式的确切原因是因为它们很容易弄乱。以下是一些参考资料,可能会增加您对可疑代码的敏感性:
答案 1 :(得分:0)
SELECT id, MONTH(start_date) as month, YEAR(start_date ) as year, DATEDIFF(end_date, start_date ) as days from table-name