Rxjs 如何覆盖订阅

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

我有一种情况,我需要在一个函数中放置一个订阅,这个函数被多次调用

我的问题是,如果我调用该函数3次,是创建3个新订阅,还是原始订阅被覆盖

这个问题背后的原因是,我希望避免创建多个订阅,以免造成内存泄漏

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谢谢。这就是我想要的答案。。。