Ste*_*n G 5 javascript cross-browser ecmascript-6 es6-promise
请注意:以下是在不同浏览器上表现不同的问题.所以这可能是一个浏览器实现问题.无论如何,我会喜欢一些建议.
在我的应用程序中,我创建了一些承诺,我可能不会消费,直到将来很长一段时间.哪个应该没问题,毕竟它们是承诺.
如果解决了存储的承诺,则没有问题.我可以根据自己的需要尽可能多地消费它,也可以随心所欲地消费它.正如所料.
但是,如果被拒绝的承诺被拒绝,则存在问题.除非我在制作完成后立即消除拒绝(不确定多久),否则Chrome或Firefox中会出现一个控制台消息,表明存在未被拒绝的承诺拒绝/错误.IE不会弹出该错误.
请考虑以下代码:
console.log("About to make a promise rejection.");
var foo = Promise.reject(new Error("Foo Rejected Promise."));
console.log("Promise rejection made.");
Run Code Online (Sandbox Code Playgroud)
请注意,没有使用或消费promise foo.它只是存储起来以备将来使用.
IE上的控制台如下所示:
即将拒绝承诺.
承诺拒绝.
这是预期的.但是,Chrome上的相同代码将生成以下控制台:
即将拒绝承诺.
承诺拒绝.
未捕(承诺)错误:Foo拒绝承诺.(...)
除了围绕"未捕获"错误的措辞之外,Firefox看起来非常像Chrome.
但问题是,我打算在很久以后处理这个"错误",当时我正在消费这个承诺.仅仅有一个被拒绝的承诺不应该导致控制台错误.....如果我使用了承诺并且没有处理错误,那么应该会发生.
要模拟错误的"更晚"处理,请考虑对代码的这种更改:
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);
Run Code Online (Sandbox Code Playgroud)
现在在这种情况下,我们通过在超时后在控制台上显示某些内容来"处理"错误.现在IE仍然按照我的预期处理这个:
即将拒绝承诺.
承诺拒绝.
显示Foo拒绝的承诺.10秒后
在这种情况下,Firefox确实喜欢IE,并准确显示这些消息,并没有给我一个错误的控制台错误.
但是,Chrome仍会出现错误错误:
即将拒绝承诺.
承诺拒绝.
未捕(承诺)错误:Foo拒绝承诺.(...)
显示Foo拒绝的承诺.10秒后
所以Chrome都抱怨我的错误没有被处理,然后显示它已被处理.
似乎我可以使用以下代码来解决这一切,这看起来像是一个黑客.基本上我在创建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);
Run Code Online (Sandbox Code Playgroud)
但这是丑陋的代码.
我的问题是双重的 - 是否有某种方式来看待Chrome(以及某种程度上FireFox)正在做什么并将其视为一种恩惠?因为对我而言似乎很糟糕.其次,当你不是假装处理错误的黑客时,是否有更好的解决方法呢?
提前致谢.
任何有可能被拒绝的承诺都应该像异常一样进行处理。
承诺不会被同步链接的机会并不多。但如果不会,则需要“hack-ish”.catch(() => { })来同步处理拒绝。
Chrome 承诺拒绝行为表明了这一点
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);
Run Code Online (Sandbox Code Playgroud)
进入同一个错误处理船
try {
throw new Error("Foo"));
setTimeout(() => {
try {
throw new Error("Foo"));
} catch (err) {
console.log("Displaying " + err.message + " 10 seconds later.");
}
}, 10000);
} catch (err) {}
Run Code Online (Sandbox Code Playgroud)
异常不是要等10秒才能被next捕获try...catch然后抛出吗?它甚至不会等待一个滴答声。它需要“hack-ish”try { ... } catch (err) {}块才能按预期执行。
Bluebird 库用户长期以来已经熟知这种行为。Bluebird 具有可调整的错误处理功能,即使在大规模情况下也可以高效地调试 Promise 。
这种行为在 Angular 2 开发中也是众所周知的,它是强制使用 Zone.js 库进行承诺的。
由于 Promise 调试的价值有限并且适用于开发环境,因此可以在生产构建中修改或禁用本机 Promise 的此行为:
if (typeof DEBUG_PROMISE === 'undefined') {
window.addEventListener('unhandledrejection', (e) => {
e.preventDefault();
console.warn(e.reason);
});
}
Run Code Online (Sandbox Code Playgroud)
这是有关该主题的更多阅读内容。
| 归档时间: |
|
| 查看次数: |
526 次 |
| 最近记录: |