Promise.catch 在 IE11 中使用 polyfills 失败
Promise.catch fails in IE11 with polyfills
我在我的 Polymer 2 项目中使用 ES6、Promises 和 fetch。因为我至少需要支持 IE11,所以我正在使用 Babel(通过 polymer-build)进行转译,并使用 polyfills.io 来 polyfill fetch 和 Promise 支持。我的 polyfills.io 导入发生在任何其他导入之前,看起来像这样:
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=default,fetch&flags=gated"></script>
当我加载页面时,IE11 控制台中出现此错误:
SCRIPT438: Object doesn't support property or method 'catch'
查看我的代码,我唯一一次使用 catch 是在 Promises 中。例如:
loadSchemas() {
return APP.client
.search("+type:Schema")
.then(result => {
// Do things with results.
})
.catch(error => {
// Deal with errors.
});
}
如果我删除捕获,页面加载没有错误,但显然它不是 运行 我的错误处理代码。
为什么这没有按预期工作?它在 Firefox、Chrome 和 Safari 中运行良好。我尝试了多种不同的 promise polyfill,但仍然出现相同的错误,所以我不认为这是一个 polyfill 错误。
所以,看起来 catch 是 IE 9+ 中的保留字。我在 https://github.com/lahmatiy/es6-promise-polyfill:
找到了这条信息
catch
is a reserved word in IE<9, meaning promise.catch(func)
throws a
syntax error. To work around this, use a string to access the
property:
promise['catch'](function(err) { // ... });
Or use .then
instead:
promise.then(undefined, function(err) { // ... });
如果我修改它以避免捕获,我的代码在 IE11 中工作,如下所示:
loadSchemas() {
return APP.client
.search("+type:Schema")
.then(result => {
// Do things with results.
}, error => {
// Deal with errors.
});
}
实际上,如果您导入 /webcomponentsjs/webcomponents-lite.js polyfill(使用 Polymer 2.x),它很可能会重写 Promise polyfill。
这个 polyfill 目前有一个未解决的问题 "catch" :
建议的解决方法是:
Pin the version of the WebComponents polyfill to 1.0.7 or less.
我查看了 Promise 的 webcomponents-lite polyfill,如果以下内容不正确,它们将替换 Promise 定义(我简化了写作):
Object.prototype.toString.call(window.Promise.resolve()) == "[object Promise]"
但是,即使您从其他来源导入 Promise polyfill,它们也会呈现为 "[object Object]"
,因此它们会被替换。
注意:Promise 的 webcomponents-lite polyfill 目前也没有公开 Promise.all()
方法,这也可能是由于 Closure 编译器的上述问题。
在此问题未解决时提出的解决方法:
在 Webcomponents polyfill 之后加载你的 polyfill。
// load webcomponents polyfills
(function() {
if ('registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')) {
// browser has web components
}
else {
// polyfill web components
let e = document.createElement('script');
e.src = '/bower_components/webcomponentsjs/webcomponents-lite.js';
document.head.appendChild(e);
}
// Promise polyfill for IE11, as of 2017/09/07 webcomponents Promise polyfill is broken
// (https://github.com/webcomponents/webcomponentsjs/issues/837)
if (!window['Promise'] || !window['Promise']['reject']){
// Remove the webcomponents polyfilled Promise object
delete window.Promise;
// Add own polyfill for Promise
let e = document.createElement('script');
e.src = '/lib/promisePolyfill/promise.js'; // or polyfill.io
document.head.appendChild(e);
}
})();
我在我的 Polymer 2 项目中使用 ES6、Promises 和 fetch。因为我至少需要支持 IE11,所以我正在使用 Babel(通过 polymer-build)进行转译,并使用 polyfills.io 来 polyfill fetch 和 Promise 支持。我的 polyfills.io 导入发生在任何其他导入之前,看起来像这样:
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=default,fetch&flags=gated"></script>
当我加载页面时,IE11 控制台中出现此错误:
SCRIPT438: Object doesn't support property or method 'catch'
查看我的代码,我唯一一次使用 catch 是在 Promises 中。例如:
loadSchemas() {
return APP.client
.search("+type:Schema")
.then(result => {
// Do things with results.
})
.catch(error => {
// Deal with errors.
});
}
如果我删除捕获,页面加载没有错误,但显然它不是 运行 我的错误处理代码。
为什么这没有按预期工作?它在 Firefox、Chrome 和 Safari 中运行良好。我尝试了多种不同的 promise polyfill,但仍然出现相同的错误,所以我不认为这是一个 polyfill 错误。
所以,看起来 catch 是 IE 9+ 中的保留字。我在 https://github.com/lahmatiy/es6-promise-polyfill:
找到了这条信息
catch
is a reserved word in IE<9, meaningpromise.catch(func)
throws a syntax error. To work around this, use a string to access the property:
promise['catch'](function(err) { // ... });
Or use
.then
instead:
promise.then(undefined, function(err) { // ... });
如果我修改它以避免捕获,我的代码在 IE11 中工作,如下所示:
loadSchemas() {
return APP.client
.search("+type:Schema")
.then(result => {
// Do things with results.
}, error => {
// Deal with errors.
});
}
实际上,如果您导入 /webcomponentsjs/webcomponents-lite.js polyfill(使用 Polymer 2.x),它很可能会重写 Promise polyfill。 这个 polyfill 目前有一个未解决的问题 "catch" :
建议的解决方法是:
Pin the version of the WebComponents polyfill to 1.0.7 or less.
我查看了 Promise 的 webcomponents-lite polyfill,如果以下内容不正确,它们将替换 Promise 定义(我简化了写作):
Object.prototype.toString.call(window.Promise.resolve()) == "[object Promise]"
但是,即使您从其他来源导入 Promise polyfill,它们也会呈现为 "[object Object]"
,因此它们会被替换。
注意:Promise 的 webcomponents-lite polyfill 目前也没有公开 Promise.all()
方法,这也可能是由于 Closure 编译器的上述问题。
在此问题未解决时提出的解决方法:
在 Webcomponents polyfill 之后加载你的 polyfill。
// load webcomponents polyfills
(function() {
if ('registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')) {
// browser has web components
}
else {
// polyfill web components
let e = document.createElement('script');
e.src = '/bower_components/webcomponentsjs/webcomponents-lite.js';
document.head.appendChild(e);
}
// Promise polyfill for IE11, as of 2017/09/07 webcomponents Promise polyfill is broken
// (https://github.com/webcomponents/webcomponentsjs/issues/837)
if (!window['Promise'] || !window['Promise']['reject']){
// Remove the webcomponents polyfilled Promise object
delete window.Promise;
// Add own polyfill for Promise
let e = document.createElement('script');
e.src = '/lib/promisePolyfill/promise.js'; // or polyfill.io
document.head.appendChild(e);
}
})();