未捕获(承诺)

Posted

技术标签:

【中文标题】未捕获(承诺)【英文标题】:Uncaught (in promise) 【发布时间】:2017-11-24 11:59:43 【问题描述】:

我知道这个问题很常见。我正在使用 es6 承诺,并且我有多个层次。 在运行时,当我没有得到承诺时,我的控制台中有Uncaught (in promise)。但事实是我确实在我的代码中发现了它。

快速简化示例:

LoginApi.js

var loginDaoCall = loginDao.login(username, password);

loginDaoCall
    .then(function (res) 
        store.dispatch(loginSuccess());
        log.log("[loginApi.login] END");
    )
    .catch(function (err) 
        store.dispatch(loginFail());
        errorUtils.dispatchErrorWithTimeout(errorLogin);
        log.log(err);
    );

return loginDaoCall;

loginContainer.js

loginApi.login(user, password).then(() => 
    // Change here instead of in render so the user can go back to login page
    this.props.history.push(baseUrlRouter + "test");
); // <- Error here cause I don't CATCH the promise, but I do catch it in my loginapi.js

我知道我什么都不做,但是嗯。我也可以在我的 API 层做历史推送,但这不是它的责任。

如何避免控制台中的错误?有办法吗?我什至在考虑就这样离开它。

【问题讨论】:

是错误还是警告? 它显示为错误,但它是一个警告,因为它不会破坏任何东西。我讨厌控制台中的警告/错误不是来自我。这是不合理的,因为这不是坏习惯恕我直言 也许是您自己的代码? errorUtils.dispatchErrorWithTimeout(errorLogin); log.log(err); 不,事实是,这是一个“未处理的拒绝”,如果我在我的 loginContainer 中捕获被拒绝的承诺,我没有错误消息。这是一个来自 es6-promises 的 console.error。 你的捕获中没有抛出错误?这是什么错误? 【参考方案1】:

你的问题是你returning 被拒绝的loginDaoCall,而不是已经处理错误的承诺。 loginApi.login(user, password) 确实返回了一个被拒绝的承诺,即使在另一个分支中处理了该承诺,进一步的 .then() 返回的承诺也确实被拒绝并且没有被处理。

你可能想做类似的事情

// LoginApi.js
return loginDao.login(username, password).then(function (res) 
    store.dispatch(loginSuccess());
    log.log("[loginApi.login] END");
    return true;
, function (err) 
    store.dispatch(loginFail());
    errorUtils.dispatchErrorWithTimeout(errorLogin);
    log.log(err);
    return false;
); // never supposed to reject

// loginContainer.js
loginApi.login(user, password).then(success => 
    if (success) 
        // Change here instead of in render so the user can go back to login page
        this.props.history.push(baseUrlRouter + "test");
    
);

【讨论】:

实际上只返回 loginDaoCall 就可以了。我真的不明白有什么不同,因为它看起来像是同一个实例,但可能不是。【参考方案2】:

听起来您的 catch 块中有错误。当错误被抛出时,没有第二个 catch 块来捕获第一个 catch 块中的错误。

修复它...

.then(function (res) 
    // some code that throws an error
)
.catch(function (err) 
    // some code that throws an error
)
.catch(function (err) 
    // This will fix your error since you are now handling the error thrown by your first catch block
    console.log(err.message)
);

【讨论】:

以上是关于未捕获(承诺)的主要内容,如果未能解决你的问题,请参考以下文章

错误:`未捕获(承诺中)类型错误:无法读取未定义的属性'doc'`

GraphQL + Apollo 错误:未捕获(承诺中)

未捕获(承诺)DOMException:超出配额

405 - 未捕获(承诺中)错误:请求失败,状态码为 405

放大未捕获的 AppSync 订阅(承诺中)

未捕获(承诺)错误:“设备”插件未在 android 上实现