为什么“未兑现承诺被拒”是一回事?

时间:2018-08-20 22:21:33

标签: javascript asynchronous promise

我了解何时发生UnhandledPromiseRejectionWarning错误。 我不明白为什么为什么编写规范时要允许这种行为。

例如,以下代码是错误的,如果callApi()拒绝,而不是我们在Node中得到UnhandledPromiseRejectionWarning错误,则在每个浏览器中都出现类似错误:

class A {
    constructor () {
        this._stuff = Promise.reject(Error('oops'))
    }
    getStuff () {
        return this._stuff
    }
}

const a = new A()

setTimeout(() => {
    a.getStuff().catch(err => console.log('I caught it!'))
}, 100)

但是为什么呢?我倾向于将承诺作为对何时发生的抽象。 如果callApi()成功,那就是诺言的行为:getStuff()的调用者将在数据可用时得到东西。

但是拒绝案例的工作方式不同。我期望发生的事情(如果以前没有被我烧死)是因为处理错误的负担落在了getStuff的调用者身上。那不是它的工作原理,但是为什么呢?

1 个答案:

答案 0 :(得分:0)

在node.js中检测到未处理的承诺拒绝是不完善的。我不确切知道它在内部如何工作,但是如果您在诺言链中没有.catch()并且诺言被拒绝,即使您将其分配给变量,然后再添加{{1} },那么它会给您“未处理的拒绝警告”。

在您的特定情况下,可能是因为您返回了事件循环,但未捕获到被拒绝的承诺-您的.catch()仅在以后的后续事件中添加。 node.js解释器无法知道您将要执行此操作。它发现事件已完成执行,并且未处理拒绝的诺言,因此创建了警告。

为避免该警告,您将不得不对其进行不同的编码。您并没有真正展示出真实的用途,因此我们可以看到您要完成的工作以提出具体建议。像其他类型的事情一样,处理此问题的最佳方法因实际情况而异。


如果您要问为什么未处理的拒绝是一个警告,那么那是因为它可能是一个严重的错误,如果没有警告,那么它将简单地失败并且开发人员永远都不是明智的选择。这非常类似于同步代码中的未处理异常。这是一个严重的错误,并中止了程序。 node.js已经通知了一段时间,未处理的拒绝可能会在以后得到相同的处理。目前,这只是一个警告。