Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reconciliate Zone.js promises with core-js #319

Closed
michaelbazos opened this issue Jul 21, 2017 · 4 comments
Closed

Reconciliate Zone.js promises with core-js #319

michaelbazos opened this issue Jul 21, 2017 · 4 comments

Comments

@michaelbazos
Copy link

The title of the issue is a bit abstract. Here is the situation:

Zone.js script, used notably by Angular framework, overrides Promise implementation with so called ZoneAwarePromise.

Now, if you load a library which relies on core-js/es6/promise, Zone promises are not considered compliant by core-js check. As a consequence, the Zone promises are replaced, but that leads to fatal consequences for the application.

Here is a fiddle including both zone and core-js unminified scripts: demo

I am aware that it might be something to change on Zone side, but I'm first raising the issue here as I want to understand what's going on with core-js check. Below is the relevant part:

var USE_NATIVE = !!function () {
  try {
    // correct subclassing with @@species support
    var promise = $Promise.resolve(1);
    var FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function (exec) {
      exec(empty, empty);
    };
    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
    return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
  } catch (e) { /* empty */ }
}();

The above "@@species test" materialised by promise.then(empty) instanceof FakePromise; returns false.

Could you please elaborate on what Zone is missing to pass this test?

@loganfsmyth
Copy link
Contributor

Promise.prototype.then is supposed to return an instance of whatever promise constructor is assigned to instance.constructor[Symbol.species] else default to the default, so in that particular test is should be an instance of FakePromise. It sounds like that part probably isn't implemented, so it always returns an instance of your replacement implementation?

See https://tc39.github.io/ecma262/#sec-promise.prototype.then and https://tc39.github.io/ecma262/#sec-speciesconstructor

@zloirock
Copy link
Owner

@loganfsmyth right.

Anyway, core-js should be loaded before zone.js.

@michaelbazos
Copy link
Author

@loganfsmyth Thanks for the hint and the links, that's helpful.

@TazmanianD
Copy link

TazmanianD commented Nov 22, 2019

My application has just hit this as well. There was an issue filed in the zone.js repo but it got closed and the repo was archived. I filed a new issue in the Angular repo to address this: angular/angular#33989.

The workaround we ended up using was to just conditionally load the polyfill:

if (!window.Promise) {
  require('core-js/modules/es.promise');
}

Another option we considered was telling the host application to save a reference to the Promise and then restore it after our script was executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants