Promise.catch не работает в IE11 с полифилами

Я использую ES6, Promises и fetch в своем проекте Polymer 2. Поскольку мне нужно поддерживать как минимум IE11, я транспилирую с помощью Babel (через полимерную сборку) и использую polyfills.io для полифил-выборки и поддержки 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 только в промисах. Например:

loadSchemas() {
  return APP.client
    .search("+type:Schema")
    .then(result => {
      // Do things with results.
    })
    .catch(error => {
      // Deal with errors.
    });
}

Если я удаляю ловушку, страница загружается без ошибок, но тогда, очевидно, мой код обработки ошибок не выполняется.

Почему это работает не так, как ожидалось? Он отлично работает в Firefox, Chrome и Safari. Я пробовал несколько разных полифиллов обещаний, но по-прежнему получал ту же ошибку, поэтому не думаю, что это ошибка полифилла.


person ittupelo    schedule 29.08.2017    source источник


Ответы (2)


На самом деле, если вы импортируете полифилл /webcomponentsjs/webcomponents-lite.js (с Polymer 2.x), он, скорее всего, переписывает полифилл Promise. И у этого полифилла в настоящее время есть открытая проблема с "уловкой":

https://github.com/webcomponents/webcomponentsjs/issues/837

Предлагаемое обходное решение:

Закрепите версию полифила WebComponents 1.0.7 или ниже.

Я взглянул на полифилл webcomponents-lite для Promise, и они заменяют определение Promise, если следующее неверно (я упростил написание):

Object.prototype.toString.call(window.Promise.resolve()) == "[object Promise]"

Однако даже если вы импортируете полифилы Promise из других источников, они будут отображаться в "[object Object]", поэтому они будут заменены.

Примечание: полифилл webcomponents-lite для Promise в настоящее время также не предоставляет метод Promise.all(), это также, вероятно, связано с вышеуказанной проблемой с компилятором Closure.

Предлагаемый обходной путь, пока эта проблема не устранена:

Загрузите ваш полифилл после полифила Webcomponents.

// 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);
    }
})();
person Jean-Rémi    schedule 07.09.2017
comment
К сожалению, мне нужны более новые версии полифила WebComponents для исправления других ошибок, поэтому привязка к 1.0.7 для меня не сработает. Приятно знать, что на самом деле это ошибка, которая (надеюсь) будет исправлена. - person ittupelo; 08.09.2017
comment
Действительно ! В конце концов, я решил загрузить (при необходимости) полифил Promise после полифила WebComponents. Чтобы определить, нужно ли это, просто проверьте, существует ли свойство reject: if (! Window ['Promise'] ||! Window ['Promise'] ['reject']) {/ * Загрузить полифилл * /} - person Jean-Rémi; 11.09.2017
comment
Для меня ничто из того, что я пробовал, никогда не могло решить проблему ... :-( Как такое может быть ??? - person Andrea; 12.09.2017
comment
Проблема WebComponent закрыта и объединена (github.com/webcomponents/webcomponentsjs/issues/837), так что следующая версия webcomponentsjs должна работать. - person Jean-Rémi; 13.09.2017
comment
Я подтвердил, что теперь catch работает с недавно выпущенной 1.0.11 webcomponentsjs. Я ловлю, что теперь работает на IE11, как и ожидалось. - person ittupelo; 15.09.2017