Zone.js检测到ZoneAwarePromise`(window | global).Promise`已被覆盖

时间:2019-09-18 15:25:28

标签: javascript node.js angular typescript ecmascript-6

我试图在我的应用程序中使用Typeform库,但是我有很多问题。加载js脚本后,“ Angular”区域错误,我收到此消息:

  

错误:Zone.js检测到ZoneAwarePromise (window|global).Promise已被覆盖。   最可能的原因是在Zone.js之后加载了Promise polyfill(加载zone.js时不需要填充Promise api。如果必须加载一个,请在加载zone.js之前执行。)

我的app.component.ts的代码是:

import { Component, Inject, AfterViewInit} from '@angular/core';
import { DOCUMENT } from '@angular/common';
import * as typeformEmbed from '@typeform/embed';

@Component({
  selector: 'my-app',
  template: `<div #my_typeform></div>`,
})


export class AppComponent implements AfterViewInit {
  constructor(
    @Inject(DOCUMENT) private document: Document
  ){}

  ngAfterViewInit() {
    const element = this.document.getElementById.call(document, 'my_typeform');
    typeformEmbed.makeWidget(element, 'https://jonathan.typeform.com/to/zvlr4L', { onSubmit: () => console.log('Close') });
  }
}

我尝试手动运行ngZone以确保它在Angular区域内运行,但是没有用。在这种情况下,app.component.ts就像

import { Component, Inject, AfterViewInit, NgZone} from '@angular/core';
import { DOCUMENT } from '@angular/common';
import * as typeformEmbed from '@typeform/embed';

@Component({
  selector: 'my-app',
  template: `<div #my_typeform></div>`,
})


export class AppComponent implements AfterViewInit {
  constructor(
    @Inject(DOCUMENT) private document: any,
    @Inject(NgZone) private ngZone: NgZone
  ){}

  ngAfterViewInit() {
    this.ngZone.run(() => {
      const element = this.document.getElementById.call(document, 'my_typeform');
      typeformEmbed.makeWidget(element, 'https://jonathan.typeform.com/to/zvlr4L', { onSubmit: () => console.log('Close') });
    });
  }
}

我也试图在我的polyfill.ts文件中导入“ zone.js / dist / zone-patch-rxjs”,但是它也不起作用。

您可以看到一个包含最少代码的项目,可以在https://stackblitz.com/edit/angular-issue-repro2-daytbo

中重现该项目。

任何线索或帮助都非常欢迎!

谢谢!

2 个答案:

答案 0 :(得分:2)

对于那些仍在寻找非常简单的解决方案的人,这对我有用。

第1步)在引导之前将import 'zone/dist/...'的文件从polyfill.ts文件移到main.ts文件。

因此,在您的main.ts文件中,您应该具有以下内容:

import 'zone.js/dist/zone'  // Included with Angular CLI.

platformBrowserDynamic()
    .bootstrapModule(AppModule, { ngZone: new NgZone({}) })

并且只需确保已将其从polyfill.ts文件中完全删除

第2步)获利。


好的,所以让我解释一下实际发生的事情(我注意到):

在某些竞争条件下,zone.js模块覆盖原始承诺后,偶尔会添加polyfilled promise。这就是导致Zone识别出它已被替换并引发该错误的原因。

无论导入polyfill.ts的顺序如何,都发生了这种情况。

我最初尝试将zone.js的加载程序放入具有较短计时器(100毫秒)的超时中。这样做可以防止我们所有人都看到错误消息,但是有时候触发速度不够快,无法在触及引导程序之前,迅速加载zone.js模块。

所以很明显,这引起了比赛状况。 (由我自己创造。)

当时的想法是在装入引导程序之前,最后一次zone.js正式导入。我想确保一切正常:

我可以通过在console.logmain.ts文件中放入polyfill.ts来测试这一点。我看到的是polyfill.ts总是在main.ts之前加载。

因此,将import 'zone.js/dist/zone'行放在main.ts中可以彻底解决此问题。然后,您的polyfill.ts文件可以自由导入并加载任何必需的模块,然后导入该zone.js文件。

答案 1 :(得分:0)

不确定,但是您可以尝试一下。

将这些添加到您的polyfill

import 'core-js/es6';
import 'core-js/es7/reflect';
import "zone.js/dist/zone";

很少有链接可以尝试

https://github.com/angular/zone.js/issues/465

https://github.com/angular/angular/issues/31724