javascript – 我应该在异步函数中抛出错误或返回被拒绝的承诺吗?

参见英文答案 > Should an async API ever throw synchronously?                                    3个
我正在使用AWS JS SDK提供的承诺.当我创建包装AWS SDK的异步函数时,我正在做的主要内容如下所示:

module.exports.myCustomFunction = input => {

    if (badInput) {
        throw new Error('failed') // <-- This is they key line
    }

    return sns.createTopic(someParams).promise()
}

// The caller looks like this:
myModule.myCustomFunction(someInput).then(result => {
    // carry on
})
.catch(err => {
    // do something with the error
})

有人说我不应该在这些基于承诺的函数中抛出错误.他们建议改为返回Promise.reject(‘失败’).说实话,我不是那么精通承诺,所以他们的解释有点过了我的脑袋.

最佳答案
他们是对的.

对myCustomFunction的调用假定始终返回一个promise(.then和.catch分别处理已解析和拒绝的promise).抛出错误时,该函数不会返回promise.

您可以使用它来捕获错误:

try {
  myModule.myCustomFunction(someInput).then(result => {
    // carry on
  })
  .catch(err => {
    // do something with the error
  })
} catch(err) {
  ...
}

但正如您所看到的,这导致两个错误处理程序:try / catch用于同步抛出的错误,而.catch用于sns.createTopic(someParams)可能返回的任何被拒绝的promise.

这就是为什么使用Promise.reject()更好的原因:

module.exports.myCustomFunction = input => {

    if (badInput) {
        return Promise.reject('failed');
    }

    return sns.createTopic(someParams).promise()
}

然后,.catch将捕获两种类型的错误/拒绝.

注意:对于较新版本的Node.js(相信v7.6及更高版本),以下内容也适用:

module.exports.myCustomFunction = async input => {

    if (badInput) {
        throw new Error('failed');
    }

    return sns.createTopic(someParams).promise()
}

这里的关键是async关键字.通过使用此关键字,函数结果将自动包含一个promise(类似于@peteb的答案所示).

转载注明原文:javascript – 我应该在异步函数中抛出错误或返回被拒绝的承诺吗? - 代码日志