【问题标题】:Async UnhandledPromiseRejectionWarningAsync UnhandledPromiseRejectionWarning
【发布时间】:2020-01-02 14:08:42
【问题描述】:

我正在使用 Promise.reject

我收到此警告:未处理的承诺拒绝警告:版本未发布

我该如何解决这个警告?我正在尝试使用 try and catch

感谢您的帮助

 public async retrieveVersionFromJira(versionName: string): 
 Promise<ReleaseVersion> {
    const searchVersionsUri = config.jiraApiUri + 'versions';
    const jsonResp = await this.jiraClient.get(searchVersionsUri);
    const version: any = jsonResp.find(version => {
        if (version.name == versionName) {
            if (version.released == true) {
                try{
                  return Promise.reject("version " + versionName + " is not released");
               }
               catch{
                 return Promise.reject("error test")
               }
            }
        }
    });
    if (!version) {
        return Promise.reject("missing version " + versionName + " on jira");
    }
    return new ReleaseVersion(version.id, version.name, version.released);
}

【问题讨论】:

  • 什么是jsonRespfind 代码看起来很可疑。
  • JsonResp 是一个 JSON 响应,都是来自 Jira 的数据,正因为如此,我有一个 JSON 结构
  • 所有应有的尊重,这告诉我什么。它是什么?数组?一个东西?包含 JSON 的字符串?
  • 是的,它是一个数组
  • 好的,我已经更新了我的答案。

标签: javascript typescript promise


【解决方案1】:

大概有两个问题:

  1. 不处理拒绝。这个问题不在retrieveVersionFromJira 中,而是在代码中使用它。该代码需要处理它可能拒绝其承诺的事实。显然,使用它的代码只是处理成功,而不是失败。

    Promise 的基本规则之一(因此,async 函数返回 Promise)是您必须处理拒绝(错误),或者将 Promise 传递给将处理拒绝的调用函数。

    如果您从 async 函数调用它,该函数将自动将拒绝传递给 调用者(它应该传递或处理它)。如果您使用顶级 async 函数,它需要永远不要拒绝(通过使用 try/catch 捕获其中发生的所有错误/拒绝),如下所示:

    // If this is the top level
    (async function() {
        try {
            const version = retrieveVersionFromJira("name");
            // ...use `version`...
        } catch {
            // Handle/report error
        }
    })();
    

    如果您从非async 函数调用它,该函数还必须将承诺链返回给它的调用者(它应该传递它或处理拒绝)或处理程序拒绝,例如:

    // Pass it on
    function someFunction() {
        return retrieveVersionFromJira("name")
            .then(version => {
                // ...use the result...
            });
    }
    
    // Or handle rejection
    function someFunction() {
        retrieveVersionFromJira("name")
        .then(result => {
            // ...use the result...
        })
        .catch(error => {
            // Handle/report the error
        });
    }
    
  2. retrieveVersionFromJira 中调用jsonResp.find 的代码不正确。您说过jsonResp 是一个数组¹。 Array.prototype.find 期望回调返回一个真值或假值,指示当前条目是否是您要查找的条目。您的代码尝试从 within 回调中从 retrieveVersionFromJira 返回,但它无法做到。您还有if (version.released == true),后跟return Promise.reject("version " + versionName + " is not released");,这似乎没有意义。你可能想要:

    const version: any = jsonResp.find(version => version.name === versionName);
    if (version && !version.released) {
        return Promise.reject("version " + versionName + " is not released");
    }
    

    ...但请参阅下面的注释,关于 return Promise.reject(...) 不是处理拒绝来自 async 函数的承诺的最佳方式。

    ¹ ...在这种情况下,它不是 JSON。 JSON 是一种用于数据交换的 文本 表示法。如果您正在处理 JavaScript 源代码,而不是处理 字符串,那么您就不是在处理 JSON。


旁注:虽然这不是问题,但retrieveVersionFromJira 中的代码不应该使用Promise.reject。请参阅this question's answers,拒绝来自async 函数的承诺的方法是使用throw。在您使用过return Promise.reject(x); 的任何地方,您都应该使用throw x;。此外,由于拒绝是错误的,通常最好使用Error 实例(例如,throw new Error("missing version " + versionName + " on jira");

【讨论】:

  • @jeremy - 不,你不会那样做的。再说一遍:问题不在于该函数,而在于调用该函数的代码。
  • @jeremy - 另外:SO 的工作方式,问题并不是要移动的目标,您不会编辑问题来尝试折叠答案。我已经回滚了那个编辑。
  • 好的,这个功能没必要改了,我在试试
猜你喜欢
  • 2021-08-21
  • 2019-07-03
  • 2019-05-04
  • 1970-01-01
  • 2018-11-05
  • 2020-06-19
  • 2019-03-16
  • 2021-08-07
  • 1970-01-01
相关资源
最近更新 更多