【问题标题】:Is it possible to store observable data into another observable是否可以将可观察数据存储到另一个可观察数据中
【发布时间】:2018-05-12 14:33:59
【问题描述】:

我试图从下面的 observable 中获取名字数组,其响应来自 API(这里是硬编码)我想将初始数据存储在另一个 observable 中。所以我实现的是:

this.initialData=Observable.of({
      data: [
        {
          firstName: 'steve',
          lastName: 'jobs'
        },
        {
          firstName: 'steve1',
          lastName: 'jobs1'
        }
      ]
    })   .map(res => {
        this.wantToAchieveObs$ = Observable.of(res.data);
        return res.data; 
      })
      .switchMap(dataArray => {
        return from(dataArray);
      })
      .bufferCount(5)
      .map((singleArray: any) => {
        return singleArray.map(_ => _.firstname);
      })

但是我没有从 wantToAchieveObs$ 获得可观察的数据,我不想再次为相同的数据再次命中 API。这是否可以通过任何其他方式实现,因为我也在尝试在 combineLatest 方法中使用这个 observable。

【问题讨论】:

    标签: angular rxjs observable


    【解决方案1】:

    您可以尝试以下方法:

    const cached$ = wantToAchieveObs$.shareReplay(1);
    

    现在您可以使用cached$ 代替wantToAchieveObs$

    wantToAchieveObs$ 的最后一个值始终存储在 cached$ 中。

    如果您想存储更多值,请使用 shareReplay(2) 之类的东西来存储最后 2 个值。

    【讨论】:

    • 我没有得到这个定义,因为我没有收到值并且我正在定义 const cached$
    【解决方案2】:

    您可能想要在您的服务中使用BehaviorSubject。这有点取决于你想做什么,但你可以这样做:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    // Your imports might be different if you use angular 6
    import { Observable } from 'rxjs/Observable';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    import 'rxjs/add/operator/filter';
    
    @Injectable()
    export class Service {
    
        // We use this variable to find out if a request to the backend has already been issued.
        private _hasRequested = false;
        // The behavior subject will keep track of the data
        private _subject: BehaviorSubject<any>;
        // This is the observable with the data. You should not expose the subject directly
        // all you want is to expose an observable.
        private _data$: Observable<any>;
    
        constructor(private http: HttpClient) {
            // BehaviourSubjects need an initial value. We can use undefined
            this._subject = new BehaviorSubject<any>(undefined);
            // Map the subject into an observable.
            this._data$ = this._subject
                .asObservable()
                // We filter out undefined values as we only want to be notified when there is data
                .filter(data => data !== undefined);
        }
    
        // This method can be used by users of the service.
        // getData().subscribe() will issue a call to the backend when it is called for
        // the first time.
        getData(): Observable<any> {
            // Check if a backend request has already been issued
            if (!this._hasRequested) {
                // If not, issue a request and change the flag to true, so we don't do this again
                this.refresh();
                this._hasRequested = true;
            }
            // Return the data observable
            return this._data$;
        }
    
        // In case you need to refresh the data that has been loaded, you
        // can use the refresh method to get a newer value from the backend
        refresh() {
            this.http.get('path/to/data')
            .subscribe(
                response => this._subject.next(response),
                error => this._subject.error(error)
            );
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 2014-01-28
      • 2019-12-31
      • 2017-03-13
      • 2011-06-17
      • 2019-05-21
      相关资源
      最近更新 更多