英文:
angular memory leak need to know how to solve leak
问题
我有一个代码正在泄漏,我需要知道为什么或者如何正确取消订阅。即使当我添加了一个包含所有对象的数组时,订阅仍然在泄漏。
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { delay, tap, mergeMap, repeat } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
postId;
callOmni = () => of(this.pollOmni()).pipe();
display = response => {};
poll = of({}).pipe(
mergeMap(_ => this.callOmni()),
tap(this.display),
delay(10),
repeat()
);
constructor(private http: HttpClient) { }
pollOmni() {
// 简单的带有 JSON 主体和响应类型<any>的 POST 请求
this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' }).subscribe(
data => {
this.postId = data;
console.log(this.postId);
},
error => {
console.log('出错', error)
}
);
}
ngOnInit() {
// 简单的带有 JSON 主体和响应类型<any>的 POST 请求
this.poll.subscribe();
}
}
英文:
I have a code that is leaking and I need to know why or how to unsubscibe correcly .
since even when I added an array that is all objects subscibed are being deleted it still leaks
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { delay, tap, mergeMap, repeat } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
postId;
callOmni = () => of(this.pollOmni()).pipe();
display = response => {};
poll = of({}).pipe(
mergeMap(_ => this.callOmni()),
tap(this.display),
delay(10),
repeat()
);
constructor(private http: HttpClient) { }
pollOmni() {
// Simple POST request with a JSON body and response type <any>
this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' }).subscribe(
data => {
this.postId = data;
console.log(this.postId);
}),
error => {
console.log('oops', error)
}
}
ngOnInit() {
// Simple POST request with a JSON body and response type <any>
this.poll.subscribe();
}
}
答案1
得分: 1
在你的代码中,似乎在pollOmni()
方法内有一个订阅,而这个方法被多次调用。这可能会导致多个未取消订阅的活跃订阅,从而引发内存泄漏问题。
为了解决这个问题,你需要确保在不再需要时取消订阅。一种方法是将订阅存储在一个变量中,并在需要时进行取消订阅。
以下是实现必要更改的代码更新版本:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of, Subject } from 'rxjs';
import { delay, tap, mergeMap, repeat, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
postId;
private ngUnsubscribe = new Subject<void>(); // 用于取消订阅的 Subject
constructor(private http: HttpClient) { }
callOmni = () => of(this.pollOmni()).pipe();
display = response => {
// 在这里添加显示逻辑
};
poll = of({}).pipe(
mergeMap(_ => this.callOmni()),
tap(this.display),
delay(10),
repeat(),
takeUntil(this.ngUnsubscribe) // 当 ngUnsubscribe 发出信号时取消订阅
);
pollOmni() {
return this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' });
}
ngOnInit() {
this.poll.subscribe();
}
ngOnDestroy() {
this.ngUnsubscribe.next(); // 发出信号以取消正在进行的订阅
this.ngUnsubscribe.complete(); // 完成 Subject
}
}
请注意,我只翻译了代码部分,没有包含其他内容。
英文:
In your code, it seems that you have a subscription inside the pollOmni() method, which is called multiple times. This can lead to multiple active subscriptions that are not unsubscribed, causing a memory leak.
To fix this, you need to make sure that you unsubscribe from the subscription when it's no longer needed. One way to achieve this is by storing the subscription in a variable and unsubscribing from it when necessary.
Here's an updated version of your code that implements the necessary changes:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of, Subject } from 'rxjs';
import { delay, tap, mergeMap, repeat, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
postId;
private ngUnsubscribe = new Subject<void>(); // Subject for unsubscribing
constructor(private http: HttpClient) { }
callOmni = () => of(this.pollOmni()).pipe();
display = response => {
// Display logic here
};
poll = of({}).pipe(
mergeMap(_ => this.callOmni()),
tap(this.display),
delay(10),
repeat(),
takeUntil(this.ngUnsubscribe) // Unsubscribe when ngUnsubscribe emits
);
pollOmni() {
return this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' });
}
ngOnInit() {
this.poll.subscribe();
}
ngOnDestroy() {
this.ngUnsubscribe.next(); // Emit value to unsubscribe from ongoing subscriptions
this.ngUnsubscribe.complete(); // Complete the subject
}
}
答案2
得分: 0
export class AppComponent implements OnInit, OnDestroy {
...
ngOnDestroy(): void {
this.poll.unsubscribe();
}
}
英文:
Something like that:
export class AppComponent implements OnInit, OnDestroy {
...
ngOnDestroy(): void {
this.poll.unsubscribe();
}
}
答案3
得分: 0
在你的代码中实现Angular中的OnDestroy
生命周期钩子,并在ngOnDestroy
方法中进行unsubscribe
操作,如下所示:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { delay, tap, mergeMap, repeat, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
postId;
private unsubscribe = new Subject<void>();
callOmni = () => of(this.pollOmni()).pipe();
display = response => {};
poll = of({}).pipe(
mergeMap(_ => this.callOmni()),
tap(this.display),
delay(10),
repeat(),
takeUntil(this.unsubscribe)
);
constructor(private http: HttpClient) { }
pollOmni() {
this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' }).subscribe(
data => {
this.postId = data;
console.log(this.postId);
},
error => {
console.log('oops', error);
}
);
}
ngOnInit() {
this.poll.subscribe();
}
ngOnDestroy(): void {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
如果上述方法对你不起作用,我建议在Angular中实现模板机制,使用Angular Async Pipe
。请参考以下示例来使用pipes
在Angular中实现模板机制:
@Component({
selector: 'app-stock',
template: `
<div *ngIf="stocks$ | async as stocks">
<ul>
<li *ngFor="let stock of stocks">
{{ stock.symbol }}
</li>
</ul>
</div>
`,
styleUrls: ['./stock.component.scss'],
})
export class StockComponent implements OnInit {
stocks$: Observable<Stock[]> = this.stockService.getStocks();
constructor(private stockService: StockService) {}
ngOnInit(): void {}
}
请注意,上述是示例实现。
英文:
In your code implement the OnDestroy
Life cycle hook in angular and unsubsribe
it in ngOnDestroy
mehthod like below:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { delay, tap, mergeMap, repeat } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
postId;
private unsubscribe = new Subject<void>();
callOmni = () => of(this.pollOmni()).pipe();
display = response => {};
poll = of({}).pipe(
mergeMap(_ => this.callOmni()),
tap(this.display),
delay(10),
repeat(),
takeUntil(this.unsubscribe)
);
constructor(private http: HttpClient) { }
pollOmni() {
this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' }).subscribe(
data => {
this.postId = data;
console.log(this.postId);
}),
error => {
console.log('oops', error)
}
}
ngOnInit() {
this.poll.subscribe();
}
ngOnDestroy(): void {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
If the above does not works for you I suggest to implement the template mechanism in Angular Angular Async Pipe
Please refer the below sample on usage of pipes
in Angular.
Please note that Below is sample implementaions:
@Component({
selector: 'app-stock',
template: `
<div *ngIf="stocks$ | async as stocks">
<ul>
<li *ngFor="let stock of stocks">
{{ stock.symbol }}
</li>
</ul>
</div>
`,
styleUrls: ['./stock.component.scss'],
})
export class StockComponent implements OnInit {
stocks$: Observable<Stock[]> = this.stockService.getStocks();
constructor(private stockService: StockService) {}
ngOnInit(): void {}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论