首页 > 解决方案 > Async UnhandledPromiseRejectionWarning

问题描述

我正在使用 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);
}

标签: javascripttypescriptpromise

解决方案


大概有两个问题:

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

    Promise(以及返回 Promise 的函数)的基本规则之一async是,您必须要么处理拒绝(错误),要么将 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期望回调返回一个真值或假值,指示当前条目是否是您要查找的条目。您的代码尝试从回调中返回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. 看到这个问题的答案,拒绝async函数承诺的方法是使用throw. 您使用过的任何地方都return Promise.reject(x);应该使用throw x;. 此外,由于拒绝是错误,通常最好使用Error实例(例如,throw new Error("missing version " + versionName + " on jira");.


推荐阅读