是否可以将可观察数据存储到另一个可观察的

时间:2018-05-12 14:33:59

标签: angular rxjs observable

我试图从下面的observable中获取firstnames数组,其响应来自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 $获得一个observable,我不想再次为这个相同的数据再次点击API。这是否可以通过任何其他方式实现,因为我也尝试在combineLatest方法中使用此observable。

2 个答案:

答案 0 :(得分:0)

您可以尝试以下内容:

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

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

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

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

答案 1 :(得分:0)

您可能需要在服务中使用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)
        );
    }

}