问题
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
It's considered an anti-pattern and usually frowned upon since you lose the async behavior.
Say the statement
this.viewUser = this.commonService.messageSource.getValue();is executed before the functionsendMessage()in the service, you'd be assigning the valuenullto the variablethis.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