【问题标题】:how to access variable of subscribe block of behaviour subject outside the block如何访问块外行为主体的订阅块变量
【发布时间】:2021-01-01 21:03:02
【问题描述】:

我正在使用行为主题并在 ts 文件中订阅它。

试图访问 ts 文件中主题块之外的变量..

service.ts 的代码


 private messageSource = new BehaviorSubject<any>(null);

  constructor(
    private apiService: ApiService
  ) {
  }

  // try

  sendMessage(value: any) {
   this.messageSource.next(value);
  }

  get getMessage() {
    return this.messageSource.asObservable();
    
   }```

now in TS file

ngOnInit() {

// this.viewUser = this.commonService.getMessage;

this.subscription = this.commonService.getMessage.subscribe(value => {
  this.viewUser = value; 
  console.log(this.viewUser)
 });


 console.log(this.viewUser)

}

显示数据的文件控制台.. 但在第二个控制台中,它显示了行为主体的初始值,即。空值 如何获取块外的数据

【问题讨论】:

  • 你有没有试过将messageSource公开,直接订阅(不使用asObservable()方法?
  • 是的,我试过了。

标签: angular typescript rxjs


【解决方案1】:

通过使用TypeScript Setter and Getter 而不是 Observable(我们必须取消订阅以防止内存泄漏)在兄弟组件之间共享数据的最简单方法。

service.ts

  _message: string;

  set message(value: any) {
    this._message = value;
  }

  get message() {
    return this._message;
  }

从任何组件或服务等设置值

this.commonService.message = 'some message'; 

最终在没有任何订阅等的情况下获得价值

ngOnInit() {
 this.viewUser = this.commonService.message
 console.log(this.viewUser);
}

【讨论】:

    【解决方案2】:

    Observables 是处理async 请求的新方法。订阅Observables 与调用function 非常相似。但是Observables 的不同之处在于它们能够返回多个称为streams 的值。Observables 不仅能够同步返回值,还能够异步返回。

    在您的情况下,首先执行第二个console.log(this.viewUser),它没有使用订阅初始化,因此您首先获得null,然后评估您的subscription。你可以试试这个:

    app.component.ts

    ngOnInit() {
      this.subscription = this.commonService.getMessage.subscribe(value => {
        this.viewUser = value; 
        console.log(this.viewUser)
        this.logViewUser();
      });
    }
    
    logViewUser() {
      console.log(this.viewUser)
    }
    
     console.log(this.viewUser)
    

    【讨论】:

      【解决方案3】:

      通常我会说没有方法可以同步访问异步变量(此处为this.viewUser)。

      但是,由于您使用的是BehaviorSubject,因此存在一种同步访问它的值的厚颜无耻的方法。如果您注意到,将使用默认值创建 BehaviorSubject。换句话说,它总是有一些价值。 RxJS 提供了一个getValue() 函数(或value getter - 它们是同义词)来同步获取BehaviorSubject 持有的值。因此,在您的情况下,您可以执行以下操作

      服务

      public messageSource = new BehaviorSubject<any>(null);   // <-- public
      
      constructor(private apiService: ApiService) { }
      
      sendMessage(value: any) {
        this.messageSource.next(value);
      }
      
      get getMessage() {
        return this.messageSource.asObservable();
      }
      

      组件

      ngOnInit() {
        this.viewUser = this.commonService.messageSource.getValue();
        console.log(this.viewUser);
      }
      

      有很多缺点

      1. 它被认为是一种反模式,并且由于您失去了异步行为而通常不受欢迎。

      2. 假设语句this.viewUser = this.commonService.messageSource.getValue(); 在服务中的函数sendMessage() 之前执行,您将值null 分配给变量this.viewUser。并且变量不会自动更新,类似于订阅的异步行为。

      【讨论】:

        【解决方案4】:

        subscribe 中的内容是异步运行的。

        this.subscription = this.commonService.getMessage.subscribe(value => {
          this.viewUser = value; 
          console.log(this.viewUser)
         });
        
        console.log(this.viewUser) // <-- This is running before what's inside subscribe
        

        您可以使用 async await 使函数异步和内部同步:

        this.viewUser = await this.commonService.getMessage.asPromise();
        

        包含此代码的函数应该是async

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-08
          • 1970-01-01
          • 2018-10-18
          相关资源
          最近更新 更多