javascript 返回错误和抛出错误之间的区别

umuewwlo  于 2023-01-29  发布在  Java
关注(0)|答案(2)|浏览(149)

我发现下面的代码在一个项目中,我不明白。:

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块中抛出错误呢?

kknvjkwl

kknvjkwl1#

当你设计一个函数接口并且有错误需要处理时,你有一个如何返回错误的设计选择,如果函数是同步的,您可以返回某个标记值,该值指示错误并易于与实际结果区分(在Javascript中通常为null),或者可以throw异常,或者可以返回一个对象,该对象具有指示操作成功或失败的属性。
当你有一个带有promise接口的异步操作时,你通常会用一个Error对象作为拒绝原因来拒绝Promise,以表示一个错误。这是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);
});

这个函数中还有其他迹象表明,它只是错误的代码。

  1. .then(function(value) {return value;})完全是多余和不必要的,它根本没有增加任何值,value已经是promise的解析值,不需要再声明。
    1.这个函数有时返回一个promise,有时抛出一个同步异常。
    这是一个更痛苦的使用。如果你看第一个if (!key) {语句,它返回一个Error对象是key参数没有提供。这意味着使用这个函数你必须捕捉同步异常。提供.then().catch()处理程序,并检查已解析承诺的类型,以查看它是否恰好是错误对象。这个函数用起来很糟糕,代码很糟糕.
    要按原样使用该函数,调用方可能必须执行以下操作:
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
});

比较一下这里调用者的简单性和上面的混乱。
此实现具有以下一致性:
1.它总是返回一个承诺,如果没有提供key,它返回一个被拒绝的承诺。
1.所有的错误都来自被拒绝的承诺

  1. promise解析的值始终是实际成功的值
  2. .then()处理程序没有任何用处。
n9vozmp4

n9vozmp42#

在一个异步任务中(例如,在promise中),你需要使用next(error)- throw错误不会导致错误处理中间件激活。

相关问题