我在一个项目中发现了以下代码,我不明白:
get(key, store = null) {
if (!key) {
return new Error('There is no key to get!');
}
let dbstore = this.localforage;
if (store !== null) {
dbstore = store;
}
return dbstore
.getItem(key)
.then(function(value) {
return value;
})
.catch(function(err) {
return new Error('The key (' + key + ") isn't accessible: " + err);
});
}
为什么
return new Error('There is no key to get!');
而不是 throw new Error('There is no key to get!');
?还有为什么不在
catch
中抛出错误?堵塞?
最佳答案
当你设计一个函数接口(interface)并且有错误需要处理时,你就有了如何返回错误的设计选择。如果函数是同步的,您可以返回一些指示错误并且很容易与实际结果区分开来的标记值(在 Javascript 中通常为 null
),或者您可以 throw
一个异常,或者您可以返回一个对象,该对象具有指示操作成功或失败的属性。
当您使用 promise 接口(interface)进行异步操作时,通常会拒绝 Promise
与 Error
对象作为表示错误的拒绝原因。这就是 Promise 的核心设计理论。成功以可选值解决,错误以原因拒绝。
这段代码:
return dbstore
.getItem(key)
.then(function(value) {
return value;
})
.catch(function(err) {
return new Error('The key (' + key + ") isn't accessible: " + err);
});
正在使用值或
Error
解决返回的 promise 目的。这通常不是 promise 代码的编写方式,因为它需要调用者测试解析值的类型以确定是否存在错误,这不是使用 promise 的简单、直接的方法。因此,对于您的问题,您通常会这样做:return dbstore.getItem(key).catch(function(err) {
throw new Error('The key (' + key + ") isn't accessible: " + err);
});
此函数还有其他迹象,表明它只是糟糕的代码。
.then(function(value) {return value;})
完全是多余和不必要的。它根本没有增加任何值(value)。 value
已经是 promise 的已解决值。无需再次声明。 这甚至是一个进一步的使用痛苦。如果你看第一个
if (!key) {
语句,它返回一个错误对象是key
没有提供参数。这意味着要使用此函数,您必须捕获同步异常,提供 .then()
和 .catch()
处理程序并检查已解决的 promise 的类型以查看它是否恰好是错误对象。使用此功能是一场噩梦。这是糟糕的代码。 要按原样使用该函数,调用者可能必须这样做:
let retVal = someObj.get(aKey);
if (typeof retVal === Error) {
// got some synchronous error
} else {
retVal.then(val => {
if (typeof val === Error) {
// got some asynchronous error
} else {
// got an actual successful value here
}
}).catch(err => {
// got some asynchronous error
})
}
函数实现大概应该是这样的:
get(key, store = null) {
if (!key) {
return Promise.reject(new Error('There is no key to get!'));
}
let dbstore = store || this.localforage;
return dbstore.getItem(key).catch(function(err) {
throw new Error('The key (' + key + ") isn't accessible: " + err);
});
}
然后可以这样使用:
someObj.get(aKey).then(val => {
// got some successful value here
}).catch(err => {
// got some error here
});
将这里调用者的简单性与上面的困惑进行比较。
此实现具有以下一致性:
key
没有提供,它返回一个被拒绝的 promise 。 .then()
无用的处理程序。 关于javascript - 返回错误和抛出错误的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56910169/