Zone.js检测到ZoneAwarePromise`(window | global).Promise`已被覆盖 [英] Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten

查看:592
本文介绍了Zone.js检测到ZoneAwarePromise`(window | global).Promise`已被覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use Typeform library in my application, but I have a lot problems with it. After loading the js scripts, the Angular zone is wrong and I get this message:

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

Error: Zone.js has detected that ZoneAwarePromise (window|global).Promise has been overwritten. Most likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)

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

The code of my app.component.ts is:

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就像

I have tried to run manually ngZone to ensure that it's ran inside Angular zone, but didn't work. In this case, app.component.ts was like

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",但是它也不起作用.

I have also tried to import 'zone.js/dist/zone-patch-rxjs' in my polyfill.ts file, but it didn't work either.

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

任何提示或帮助都非常欢迎!

Any clue or help is really welcome!

提前谢谢!

推荐答案

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

For those still looking for a VERY easy fix for this, this is what worked for me.

第1步)在引导程序之前将import 'zone/dist/...'内容从polyfill.ts文件移动到main.ts文件.

Step 1) Move your import 'zone/dist/...' stuff from your polyfill.ts file to your main.ts file before your bootstrap.

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

So in your main.ts file, you should have something like:

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

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

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

And just be sure you've totally removed it from your polyfill.ts file

第2步)获利.

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

OK, so let me explain what's actually happening (that I noticed):

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

There's a race condition where occasionally the polyfilled promise gets added AFTER the zone.js module overrides the native promise. This is what causes Zone to recognize that it's been replaced and throw that error.

无论我将导入内容放入polyfill.ts的顺序如何,都会发生这种情况.

This happened regardless of the order in the polyfill.ts I put the imports in.

我最初尝试将zone.js的加载器设置为具有较短计时器(100毫秒)的超时.这可以防止我们大家看到的错误消息,但是有时触发速度不够快,无法在进入引导程序之前加载zone.js模块.

I originally tried putting the loader for zone.js in a timeout with a short timer (100ms). This worked to prevent the error message we're all seeing, but occasionally didn't fire fast enough to load the zone.js module before hitting the bootstrap.

所以很明显,这导致了比赛状态. (由我自己创造.)

So obviously this was causing a race condition. (Of my own making.)

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

The thought then was to make the zone.js import OFFICIALLY last before loading the bootstrap. I wanted to make sure that was going to work:

我能够通过在main.tspolyfill.ts文件中放置一个console.log来进行测试.我看到的是polyfill.ts总是在main.ts之前加载.

I was able to test this by putting a console.log in the main.ts and the polyfill.ts files. What I saw was that the polyfill.ts is always loaded before the main.ts.

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

So placing the import 'zone.js/dist/zone' line in the main.ts solves this problem once and for all. Then your polyfill.ts file is free to pull in and load any modules necessary before getting that zone.js file imported.

这篇关于Zone.js检测到ZoneAwarePromise`(window | global).Promise`已被覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆