返回错误和抛出错误之间的区别 [英] Difference between return Error and throw Error

查看:109
本文介绍了返回错误和抛出错误之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个我不理解的项目中找到了以下代码。

I found the following code in a project, that I do not understand.:

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);
      });
  }

为什么返回新错误('没有键'); 而不是抛出新错误('没有键!');

还为什么不在 catch 块中抛出错误?

Also why not throw an error in the catch block?

推荐答案

在设计功能接口时,如果要处理错误,则可以选择如何返回错误。如果该函数是同步的,则可以返回一些指示错误的哨兵值,并且可以很容易地将其与实际结果区分开(在Javascript中通常为 null ),或者可以将抛出异常,或者您可以返回一个对象,该对象具有指示操作成功或失败的属性。

When you design a function interface and there are errors to deal with, you have a design choice for how to return errors. If the function is synchronous, you can either return some sentinel value that indicates an error and is easily distinguished from an actual result (often null in Javascript) or you can throw an exception or you can return an object that has a property that indicates the success or failure of the operation.

有一个带有promise接口的异步操作,通常会拒绝带有 Error 对象的 Promise 作为拒绝原因表示错误。这就是承诺的核心设计理论。成功通过可选值解决,错误因某种原因被拒绝。

When you have an asynchronous operation with a promise interface, one would usually reject the Promise with an Error object as the reject reason to signify an error. That's the core design theory of promises. Success resolves with an optional value, errors reject with a reason.

这段代码:

return dbstore
  .getItem(key)
  .then(function(value) {
    return value;
  })
  .catch(function(err) {
    return new Error('The key (' + key + ") isn't accessible: " + err);
  });

正在使用值或错误对象。通常,这不是承诺代码的编写方式,因为它将要求调用方测试解析值的类型,以判断是否存在错误,这不是使用承诺的简单明了的方法。因此,对于您的问题,通常应执行以下操作:

is resolving the returned promise with either a value or an Error object. This is generally not how promise code is written because it will require the caller to test the type of the resolved value to figure out if there's an error or not which is not the simple, straightforward way to use promises. So, to your question, you would usually do this:

return dbstore.getItem(key).catch(function(err) {
    throw new Error('The key (' + key + ") isn't accessible: " + err);
});

此函数还有其他迹象,那就是错误的代码。

There are other signs in this function, that it's just bad code.


  1. .then(function(value){return value;})完全多余且不必要。它根本没有增加任何价值。 已经是承诺的已解决值。不需要再次声明它。

  1. .then(function(value) {return value;}) is completely superfluous and unnecessary. It adds no value at all. The value is already the resolved value of the promise. No need to declare it again.

该函数有时返回一个promise并抛出一个同步异常。

痛苦使用。如果查看第一个 if(!key){语句,它将返回一个错误对象,该对象是 key 参数是否是没有提供。这意味着要使用此功能,您必须捕获同步异常,并提供 .then() .catch()处理程序并检查已解决的Promise的类型,以查看它是否恰好是一个错误对象。使用此功能是一场噩梦。

The function sometimes returns a promise and sometimes throws a synchronous exception.
This is even a further pain to use. If you look at the first if (!key) { statement, it returns an Error object is the key argument isn't supplied. That means that to use this function you have to catch synchronous exceptions, provide .then() and .catch() handlers AND check the type of the resolved promise to see if it happens to be an error object. This function is a nightmare to use. It's bad code.

要按原样使用该函数,调用者可能必须这样做:

To use the function as it is, the caller would likely have to do this:

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
    })
}

函数实现可能应该是这样的:

The function implementation probably should be this:

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
});

将调用者的简单性与上面的混乱进行比较。

Compare the simplicity for the caller here to the mess above.

此实现具有以下一致性:

This implementation has these consistencies:


  1. 它始终返回承诺。如果未提供 key ,它将返回被拒绝的承诺。

  2. 所有错误均来自被拒绝的承诺

  3. 承诺解决的值始终是实际的成功值

  4. 没有 .then()处理函数没有用。

  1. It always returns a promise. If key isn't supplied, it returns a rejected promise.
  2. All errors come via a rejected promise
  3. The value the promise resolves with is always an actual successful value
  4. There's no .then() handler that does nothing useful.

这篇关于返回错误和抛出错误之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆