Async UnhandledPromiseRejectionWarning

Posted

技术标签:

【中文标题】Async 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 的字符串? 是的,它是一个数组 好的,我已经更新了我的答案。 【参考方案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
        );
    
    

    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 的工作方式,问题并不是要移动的目标,您不会编辑问题来尝试折叠答案。我已经回滚了那个编辑。 好的,这个功能没必要改了,我在试试

以上是关于Async UnhandledPromiseRejectionWarning的主要内容,如果未能解决你的问题,请参考以下文章

async.map 或 async.each 与 async.parallel 有啥区别?

async.map 或 async.each 与 async.parallel 有啥区别?

ES6 之 async 异步函数

Dart 中的 async 和 async* 有啥区别?

JS async和await关键字

async / await 的串行和并行