Rxjs 如何覆盖订阅
我有一种情况,我需要在一个函数中放置一个订阅,这个函数被多次调用 我的问题是,如果我调用该函数3次,是创建3个新订阅,还是原始订阅被覆盖 这个问题背后的原因是,我希望避免创建多个订阅,以免造成内存泄漏Rxjs 如何覆盖订阅,rxjs,Rxjs,我有一种情况,我需要在一个函数中放置一个订阅,这个函数被多次调用 我的问题是,如果我调用该函数3次,是创建3个新订阅,还是原始订阅被覆盖 这个问题背后的原因是,我希望避免创建多个订阅,以免造成内存泄漏 var可观测=Rx.可观测; var subscription=新的Rx.subscription(); var数=可观察到的([1,2,3,4,5,6]); 函数foo(){ 订阅=数字。订阅(val=>console.log(“数字订阅”,val)) 订阅。取消订阅(); } foo(); f
var可观测=Rx.可观测;
var subscription=新的Rx.subscription();
var数=可观察到的([1,2,3,4,5,6]);
函数foo(){
订阅=数字。订阅(val=>console.log(“数字订阅”,val))
订阅。取消订阅();
}
foo();
foo();
foo();
更新:
import { Injectable, OnDestroy } from '@angular/core';
import { Subject, Observable, Subscription } from 'rxjs';
import { HttpClient, HttpHeaders, HttpEventType, HttpRequest, HttpErrorResponse, HttpEvent, HttpParams } from '@angular/common/http';
import { Message } from '../message/message.model';
import { GlobalsService } from '../globals/globals.service';
import { environment } from '../../environments/environment';
@Injectable()
export class MessagesService implements OnDestroy {
messages: Observable<Message[]>;
postMessages: Observable<Message[]>;
subscriptionPostMessages: Subscription;
constructor(public http: HttpClient,
public globalsService: GlobalsService) {
postMessage(message: Message): void {
const body = {
messageid: message.id,
filename: ''
};
const requestHeaders = new HttpHeaders().set('Content-Type', 'application/json');
const headers = {
headers: requestHeaders
};
this.http.post(this.globalsService.baseUrl + environment.ajax_dir + '/ajax-ng-post-message-module.cfm', body, headers).map(
(res: Response) => {
if('filename' in res && res['filename'] !== ''){
this.postMessages = this.addFileNameToMessage(res['messageid'], res['filename']);
this.subscriptionPostMessages = this.postMessages.subscribe( (messages: Message[]) => {
});
this.subscriptionPostMessages.unsubscribe();
}
return res;
})
.subscribe();
}
addFileNameToMessage(id: string, filename: string): Observable<Message[]> {
return this.messages.map( (messages: Message[]) => {
messages.map( (message: Message) => {
if(message.id === id){
message.file.filename = filename;
message.file.value = '';
}
})
return messages;
})
}
ngOnDestroy() {
if (this.subscriptionPostMessages) {
this.subscriptionPostMessages.unsubscribe();
}
}
}
我被要求显示项目中的实际代码。对于simplicty,我遗漏了很多代码,但是以下引用:
this.messages
指发射阵列的可观察物
我想安全地删除此线路:
this.subscriptionPostMessages.unsubscribe();
代码如下:
import { Injectable, OnDestroy } from '@angular/core';
import { Subject, Observable, Subscription } from 'rxjs';
import { HttpClient, HttpHeaders, HttpEventType, HttpRequest, HttpErrorResponse, HttpEvent, HttpParams } from '@angular/common/http';
import { Message } from '../message/message.model';
import { GlobalsService } from '../globals/globals.service';
import { environment } from '../../environments/environment';
@Injectable()
export class MessagesService implements OnDestroy {
messages: Observable<Message[]>;
postMessages: Observable<Message[]>;
subscriptionPostMessages: Subscription;
constructor(public http: HttpClient,
public globalsService: GlobalsService) {
postMessage(message: Message): void {
const body = {
messageid: message.id,
filename: ''
};
const requestHeaders = new HttpHeaders().set('Content-Type', 'application/json');
const headers = {
headers: requestHeaders
};
this.http.post(this.globalsService.baseUrl + environment.ajax_dir + '/ajax-ng-post-message-module.cfm', body, headers).map(
(res: Response) => {
if('filename' in res && res['filename'] !== ''){
this.postMessages = this.addFileNameToMessage(res['messageid'], res['filename']);
this.subscriptionPostMessages = this.postMessages.subscribe( (messages: Message[]) => {
});
this.subscriptionPostMessages.unsubscribe();
}
return res;
})
.subscribe();
}
addFileNameToMessage(id: string, filename: string): Observable<Message[]> {
return this.messages.map( (messages: Message[]) => {
messages.map( (message: Message) => {
if(message.id === id){
message.file.filename = filename;
message.file.value = '';
}
})
return messages;
})
}
ngOnDestroy() {
if (this.subscriptionPostMessages) {
this.subscriptionPostMessages.unsubscribe();
}
}
}
每次都会被覆盖:
postMessage()
接到电话了吗
换句话说,我一次只能激活一个订阅吗?如果您调用提供的代码,您将不会有多个订阅延迟,因为您在同一个函数调用中
subscribe
和unsubscribe
。请注意,鉴于RxJs的异步性质,这将导致在订阅的onNext
回调中收到的值量出现意外行为
我感觉您几乎遇到了rx反模式,但是您需要提供更多关于您想要归档的内容的信息,以便为您提供更好的答案。“考虑到RxJs的异步特性”,您想解释一下吗?示例中没有异步内容。@Mark van Straten如果删除“subscription.unsubscripte()”会发生什么?在任何时候都只有一个订阅吗?我试图了解是否在每次调用“foo”时都会覆盖相同的订阅?如果删除
unsubscribe()
,则只会覆盖局部变量subscription
,并最终导致多个悬空订阅(内存泄漏)。由于您的示例是有限的,因此这些将结束,但如果您使用例如Observable.interval()
ad来执行此操作,请非常小心infinitum@abetteroliver我对async本质的意思是,这个示例是同步的,正因为如此,它才起作用。一旦开始异步,代码的行为就会不同,导致错误难以解释。@Mark van Straten没有本地订阅。我不是每次调用foo()时都会覆盖全局订阅吗?如果你订阅《时代》杂志,而你的邻居也这样做,那么他们就不会收到你的副本。另一方面,您的示例中的流已经完成,那么内存泄漏会出现在哪里呢?@一个更好的奥利弗感谢您的评论。如果删除“subscription.unsubscripte()”,会发生什么情况?这段代码还可以吗?是的,如果您同时删除var subscription
。但请记住,如果流没有完成(例如,使用interval()
)创建的流),您需要按照正确的建议取消订阅。@better oliver谢谢。这就是我想要的答案。。。