how to access variable of subscribe block of behaviour subject outside the block

孤街浪徒 提交于 2021-01-29 22:10:05

问题


I am using behaviour subject and subscribe it in ts file.

trying to access the variable outside the subject block in ts file..

code for 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)

}

file console showing data.. but in second console , it is showing inital value of behaviour subject ie. null how can i get data outside the block


回答1:


What's inside your subscribe is running asynchronously.

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

You could use the async await to make the function async and whats inside sync :

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

The function containing this code should be async.




回答2:


Normally I would say there is no way to access an asynchronous variable (this.viewUser here) synchronously.

However since you're using BehaviorSubject, there exists a cheeky way to access it's value synchronously. If you notice, a BehaviorSubject is created with a default value. In other words it always holds some value. RxJS provides a getValue() function (or the value getter - they are synonymous) to synchronously get the value held by the BehaviorSubject. So in your case you could do the following

Service

public messageSource = new BehaviorSubject<any>(null);   // <-- public

constructor(private apiService: ApiService) { }

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

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

Component

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

There are multiple disadvantages

  1. It's considered an anti-pattern and usually frowned upon since you lose the async behavior.

  2. Say the statement this.viewUser = this.commonService.messageSource.getValue(); is executed before the function sendMessage() in the service, you'd be assigning the value null to the variable this.viewUser. And the variable won't be updated automatically akin to the async behavior with a subscription.




回答3:


Observables are new way of handling async requests. Subscriptions to Observables are quite similar to calling a function. But where Observables are different is in their ability to return multiple values called streams.Observables not only able to return a value synchronously, but also asynchronously.

In your case first the second console.log(this.viewUser) is executed which is not initialized with the subscription and because of that you get null first and then your subscription evaluated. You can try this:

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)



回答4:


The simplest way to share data between sibling components by using TypeScript Setter and Getter instead of an Observable (which we must need to unsubscribe to prevent memory leak).

service.ts

  _message: string;

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

  get message() {
    return this._message;
  }

Set value from any component or service etc

this.commonService.message = 'some message'; 

And finally get the value without any subscription etc

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


来源:https://stackoverflow.com/questions/63896191/how-to-access-variable-of-subscribe-block-of-behaviour-subject-outside-the-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!