代码之家  ›  专栏  ›  技术社区  ›  Himanshu Mittal

Angular 2中的生命周期DoCheck无限执行

  •  1
  • Himanshu Mittal  · 技术社区  · 7 年前

    我制作了一个基于平均堆栈的小应用程序,并在组件生命周期内使用了一种服务方法。我使用DoCheck生命周期从服务器获取新的价值,只要价值发生变化。我认为生命周期将在值更改时执行,或在固定的时间间隔内执行。

    组件屏幕截图如下:

    export class CommentsComponent implements DoCheck {
    
        comments: Comment[] = [];
    
        ngDoCheck() {
            this.commentService.getComments().subscribe((result) => {
                this.comments = result.comments;
            }, (error) => console.log(error));
        }
    
    }
    

    我所期望的是,生命周期钩子将在其他用户实际发布时或以固定时间间隔向服务器发送请求,以获取新的评论(其他用户可能已经发布),但生命周期钩子将无限地发送请求。 (很抱歉Chrome开发者工具的屏幕截图,我的电脑在加载应用程序后就会冻结)。

    export class CommentService {
      getComments () {
        return this.http.get('http://www.localhost:3000/getcomment').map(res => res.json());
      }
    }

    PS:我的应用程序在端口4200上运行,而我的后端在端口3000上运行 here .

    如果我使用OnInit lifecycle钩子,那么在生成组件后就会发出请求,尽管这不是我想要的,但它表明服务/服务使用没有错误(编码错误),生命周期钩子正在发送请求。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Armen Stepanyan Ganesh Reo    3 年前

    根据a documentaion , ngDoCheck

    每次运行更改检测时,在ngOnChanges()之后立即调用, 在第一次运行ngOnInit()之后

    注意,angular还使用 NgZone

    从…起 documentation

    要了解更改检测的工作原理,首先考虑应用程序何时需要更新HTML。通常,发生更新的原因如下:

    • 组件初始化。例如,在引导Angular应用程序时,Angular加载引导组件并触发ApplicationRef。勾选()以调用更改检测和视图渲染。

    • HTTP数据请求。您还可以通过HTTP请求从服务器获取数据。

    • 宏任务,例如setTimeout()或setInterval()。您还可以更新宏任务的回调函数中的数据,例如setTimeout()。

    • 微任务,如承诺。然后()。其他异步API返回Promise对象(例如fetch),因此then()回调函数也可以更新数据。

    • 其他异步操作。除了addEventListener()、setTimeout()和Promise。然后(),还有其他可以异步更新数据的操作。例如WebSocket。onmessage()和Canvas。toBlob()。

    在此事件之后,Angular再次运行更改检测以检测数据可能已更改。

    所以在你的代码中 Http request ngDoCheck公司 ngDoCheck公司 您再次发出http请求。这就是为什么你得到无穷循环。

    rxjs interval

    import { interval } from 'rxjs';
    ----
    export class Appcomponent {
      ngOninit() {
        interval(3000).subscribe(x => {
          this.commentService.getComments().subscribe((result) => {
            this.comments = result.comments;
          }, (error) => console.log(error));
        })
      }
    
    }