javascript - 为什么需要立即使用我的 ES6 Promise Rejection 以避免出现控制台错误消息?

标签 javascript cross-browser ecmascript-6 es6-promise

请注意:以下是在不同浏览器中表现不同的问题。所以也许这是一个浏览器实现问题。无论如何,我都希望得到一些建议。

在我的应用程序中,我创建了几个 promise ,我可能要等到 future 相当长一段时间才会使用这些 promise 。这应该没问题,毕竟它们是 promise 。

如果存储的 promise 已解决,则没有问题。我可以在未来尽可能多地使用它,并且可以多次使用它。正如预期的那样。

但是,如果被存储的 promise 被拒绝,就会出现问题。除非我在做出拒绝后不久(不确定多快)使用该拒绝,否则 Chrome 或 Firefox 中会弹出一条控制台消息,指示存在未捕获的 promise 拒绝/错误。 IE 不会弹出该错误。

因此请考虑以下代码:

console.log("About to make a promise rejection.");
var foo = Promise.reject(new Error("Foo Rejected Promise."));
console.log("Promise rejection made.");

请注意,没有使用或消耗 promise foo。它只是存储起来以备将来使用。

IE 上的控制台如下所示:

About to make a promise rejection.

Promise rejection made.

这是预期的。但是,Chrome 上的相同代码将产生以下控制台:

About to make a promise rejection.

Promise rejection made.

Uncaught (in promise) Error: Foo Rejected Promise.(…)

Firefox 看起来很像 Chrome,除了围绕“未捕获”错误的措辞。

但问题是我打算稍后处理这个“错误”,当时我正在消费 promise 。仅仅有一个被拒绝的 promise 不应该导致控制台错误......如果我消费 promise 并且不处理错误,那应该发生。

为了模拟“更晚”的错误处理,请考虑对代码的这种更改:

console.log("About to make a promise rejection.");
var foo = Promise.reject(new Error("Foo Rejected Promise."));
console.log("Promise rejection made.");
setTimeout(() => {
    foo.catch((err) => {
        console.log("Displaying " + err.message + " 10 seconds later.");
    });
}, 10000);

现在在这种情况下,我们通过在超时后在控制台上显示一些内容来“处理”错误。现在 IE 仍然按照我的预期处理这个问题:

About to make a promise rejection.

Promise rejection made.

Displaying Foo Rejected Promise. 10 seconds later.

在这种情况下,Firefox 确实像 IE,并且准确地显示了这些消息,并且没有给我一个错误的控制台错误。

然而,Chrome 仍然给出错误的错误:

About to make a promise rejection.

Promise rejection made.

Uncaught (in promise) Error: Foo Rejected Promise.(…)

Displaying Foo Rejected Promise. 10 seconds later.

所以 Chrome 既提示我的错误没有被处理,又显示它被处理了。

看来我可以使用以下看起来像 hack 的代码来解决所有这些问题。基本上我在创建 promise 时对错误进行了“假”处理,然后按照我以后想要的方式真正处理它:

console.log("About to make a promise rejection.");
var foo = Promise.reject(new Error("Foo Rejected Promise."));
foo.catch(() => { });  // Added this hack-ish code.
console.log("Promise rejection made.");
    setTimeout(() => {
    foo.catch((err) => {
        console.log("Displaying " + err.message + " 10 seconds later.");
    });
}, 10000);

但这是丑陋的代码。

我的问题是双重的——是否有某种方法可以查看 Chrome(以及某种程度上的 FireFox)正在做什么并将其视为一种帮助?因为对我来说这看起来很糟糕。其次,有没有比假装处理错误更好的方法来解决这个问题?

提前致谢。

最佳答案

任何有可能被拒绝的 promise 都应该被处理,类似于异常。

一个 promise 不会被同步链接的可能性并不大。但如果它不会,它需要“hack-ish”.catch(() => { }) 来同步处理拒绝。

Chrome promise rejection behavior put this

var foo = Promise.reject(new Error("Foo Rejected Promise."));
foo.catch(() => { });  // Added this hack-ish code.

setTimeout(() => {
    foo.catch((err) => {
        console.log("Displaying " + err.message + " 10 seconds later.");
    });
}, 10000);

进入与错误处理相同的船

try {
  throw new Error("Foo"));

  setTimeout(() => {
    try {
      throw new Error("Foo"));
    } catch (err) {
      console.log("Displaying " + err.message + " 10 seconds later.");
    }
  }, 10000);
} catch (err) {}

在被抛出之前,异常不会等待 10 秒被下一个 try...catch 捕获吗?它甚至不会等待一个滴答声。它需要“hack-ish”try { ... } catch (err) {} block 才能按预期执行。

很长一段时间以来,Bluebird 库的用户都知道这种行为。 Bluebird 具有可调整的错误处理并允许 debug promises即使在大规模上也很有效。

该行为在 Angular 2 开发中也是已知的,它是强制使用 Zone.js 库的 promise 。

由于 promise 调试的值(value)有限且适用于开发环境,因此可以在生产构建中修改或禁用 native promise 的此行为:

if (typeof DEBUG_PROMISE === 'undefined') {
  window.addEventListener('unhandledrejection', (e) => {
    e.preventDefault();
    console.warn(e.reason);
  });
}

Here's more reading关于这个问题。

关于javascript - 为什么需要立即使用我的 ES6 Promise Rejection 以避免出现控制台错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38733144/

相关文章:

javascript - imacros firefox循环遍历结果并提取

javascript - 我如何检测(并纠正?)跨浏览器的各种滚动条可见性?

javascript - 所有浏览器都支持 querySelector 吗?

javascript - 在饼图中显示值

javascript - 如何将 html 注入(inject) Angular UI Bootstrap 弹出窗口

jquery - 从 ie 隐藏特定的 css 规则

node.js - Webstorm 10 + Karma + ES6 - 单元测试

javascript - Symbol.Iterator - 传递参数

ecmascript-6 - 带有 ES6 导入的原始加载器

javascript - 返回字符串中最后一个索引的确切单词