【问题标题】:With a Promise, why do browsers return a reject twice but not a resolve twice?有了 Promise,为什么浏览器会返回两次拒绝而不是两次解析?
【发布时间】:2019-10-09 00:38:40
【问题描述】:

我无法理解 javaScript promises。我写了以下代码:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log(e)),5000);

我立即在我的 Chrome 开发者控制台中看到了这个:

但在我等待 5 秒后,消息会自动变为黑色,如下图所示:

我以前从未在我的 javaScript 代码和开发人员控制台之间看到这种行为,我的 javaScript 代码可以在开发人员控制台中“修改现有内容”。

所以我决定写下这段代码,看看resolve是否会出现同样的情况:

var p = new Promise(function(resolve,reject){

    resolve("hello world");
});

setTimeout(()=>p.then(e=>console.log(e)),5000);

但在这种情况下,我的开发者控制台直到 5 秒后才显示任何内容,然后它会打印 hello world

为什么resolvereject 在被调用时的处理方式如此不同?


额外

我也写了这段代码:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);

这会导致开发者控制台出现多个输出。在时间 0 出现红色错误,在时间 5 秒时红色变为黑色并带有文本 errors hello world,然后在时间 6 秒时出现新的错误消息 errors 2 hello world,然后在时间 7 秒时出现红色错误消息。现在我很困惑reject 实际被调用了多少次......我迷路了......

【问题讨论】:

  • 顺便说一句:var p = new Promise(function(resolve,reject){ reject(Error("hello world")); }); 可以更惯用、更简洁地写成var p = Promise.reject(Error("hello world")); :-)
  • 很棒的问题。

标签: javascript asynchronous promise


【解决方案1】:

哇,这真的很酷。我以前从未见过控制台这样做。 (不过,它有 other forms 的动态行为,所以......)这是发生了什么:

在第一种情况下,您的 setTimeout 回调代码之外的所有内容的代码执行都已完成,并且执行堆栈返回,因此只有“platform code”(正如 Promises/A+ 规范所称)正在运行,而不是用户级 JavaScript 代码(暂时)。此时,promise 被拒绝,并且没有任何处理拒绝,因此这是一个 未处理的拒绝,devtools 会向您报告它。

然后,五秒钟后,您的回调运行并附加一个拒绝处理程序。此时,拒绝不再未处理。显然,Chrome/V8/devtools 协同工作以删除来自控制台的未处理拒绝警告。相反,您看到的是您通过console.log 在拒绝处理程序中输出的内容。如果您更早地附加拒绝处理程序,您将不会收到未处理的拒绝错误。

履行不会发生这种情况,因为不处理履行不是错误情况。不处理拒绝是。

【讨论】:

  • 哦,有道理。我注意到 FireFox 处理它的方式略有不同。但是好的,现在更有意义了。
  • 我在回答中写了同样的内容,但是加载了你的,所以我没有发布我的。很好的解释! +1
猜你喜欢
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多