RxJs 从 observable 中获取价值

Posted

技术标签:

【中文标题】RxJs 从 observable 中获取价值【英文标题】:RxJs get value from observable 【发布时间】:2016-10-03 02:23:39 【问题描述】:

在组件中:

singleEvent$: Observable<Event>;

在初始化时,我可以观察到

this.singleEvent$ = this._eventService.events$
  .map(function (events) 
    let eventObject = events.find(item => item.id === eventid);
    let eventClass: Event = new Event(eventObject);
    return eventClass;
  );

我怎样才能获取像event.name 这样的当前值?

【问题讨论】:

请在问题中添加更多代码。一个笨拙的也可以。 【参考方案1】:

要从 observable 获取数据,您需要订阅:

this.singleEvents$.subscribe(event => this.event = event);

在模板中,您可以使用async pipe 直接绑定到可观察对象:

singleEvents$ | async

【讨论】:

我的订阅者在服务中但我需要在组件中取名 抱歉,我无法从您的评论中理解。 我认为他的意思是在他使用的服务中 .subscribe 然后有一个组件使用的主题(或类似内容)。假设有一个页面组件有一个接受异步输入的子组件。那么父组件需要一些数据来处理其他请求? @Mackelito 抱歉,但这并不能说明问题。如果这确实是一个困扰您的问题,那么我建议创建一个新问题,其中包含演示您尝试完成的代码的代码。 我相信他缺少的是他还需要在组件中使用 .subscribe 。 :)【参考方案2】:

为了补充 Günter Zöbauer 的回答,如果您希望同步获取 Observable 中的值,那么您可能正在寻找 BehaviorSubject。

一个 BehaviorSubject 是一个 Observable,它总是有一个值,你可以调用 myBehaviorSubject.getValue()myBehaviorSubject.value 来同步检索 BehaviorSubject 当前持有的值。

由于它本身也是一个可观察对象,您仍然可以订阅 BehaviorSubject 以异步响应它所持有的值的变化(例如 myBehaviorSubject.subscribe(event =&gt; this.event = event ))并在组件模板中使用异步管道(例如 myBehaviorSubject | async )。

这里有一些用法来匹配您给定的示例,以从给定的服务在您的组件中创建一个 BehaviorSubject:

@Component(
  //...
)
export class YourComponent implements OnInit 
  singleEvent$: BehaviorSubject<Event>;

  constructor(private eventService: EventService)

  ngOnInit()
    const eventid = 'id'; // <-- actual id could go here
    this.eventService.events$
      .pipe(
        map(events => 
          let eventObject = events.find(item => item.id === eventid);
          let eventClass: Event = new Event(eventObject);
          return eventClass;
        )
      )
      .subscribe(event => 
        if(!this.singleEvent$)
          this.singleEvent$ = new BehaviorSubject(event);
         else 
          this.singleEvent$.next(event);
        
      );
  

【讨论】:

我想要的是一个无需订阅也无需使用 BehaviorSubject 即可观察到的可观察对象,因为您可以使用 next() 对其进行修改 最近真的很喜欢 async/await API 用于可能感兴趣的类似用例@Narvalex。这个想法是你像这样使用它:const foo = await obs$.pipe(take(1)).toPromise() 在异步函数内部。 感谢您的提示。这确实是一个关于 Subject 和 BehaviourSubject 之间区别的面试问题,现在我都清楚了。 在你的组件上暴露BehaviorSubject不是有风险吗?!如果您只是暴露BehaviorSubject,那么使用Observable(克隆)有什么意义?【参考方案3】:

您可以使用observable.pipe(take(1)).subscribe 将可观察对象限制为仅获取一个值并停止侦听更多值。

let firstName: string; 

        this.insureFirstName
            .pipe(take(1))  //this will limit the observable to only one value
            .subscribe((firstName: string) => 
                this.firstName = firstName; asssgning value 
            );
        console.log(this.firstName); //accessing the value

【讨论】:

【参考方案4】:

添加到@ZackDeRose 在@Günter Zöchbauer 响应中添加的内容

private beneficiary = new BehaviorSubject<__IBeneficiary>(newBeneficiary);
beneficiary$ = this.beneficiary.asObservable();

setBeneficiaryInfo(beneficiary: __IBeneficiary): void 
    this.beneficiary.next(beneficiary);
    // when your you subscribe to beneficiary$ you would get the new value


/* when implementing in component or other function
   this.beneficiary$.subscribe(
        item => 
            // use current value
        
    );
*/

modePersonalInformation(personalInfo, mode: string): Observable<any> 
    const $beneficiary = this.beneficiary.value; 
    // this will get the current observable value without the subscrib callback function
    return this.http.post<any>(
        `$this.apiURL/$mode-biography/personal` + ((mode === 'update' && $beneficiary?.id) ? `/$$beneficiary.id` : ''),
        ...personalInfo,
        this.httpOptions
    )

您必须设置一些条件来检查您是否要使用现有对象

【讨论】:

以上是关于RxJs 从 observable 中获取价值的主要内容,如果未能解决你的问题,请参考以下文章

在 AngularFire 中检索嵌套 Firestore 查询的 RxJS Observable

[RxJS] Split an RxJS Observable into groups with groupBy

Object.observe 退出和 RxJS 和 Angular 2

将 Promise 转换为 RxJs Observable

Observable 错误,执行不同的 observable,重试原始 observable (Angular, RxJs6)

从角度 4 中的“rxjs/Observable”导入 Observable 时出错