如何根据两种不同的异步方法结果设置结果

How to set a result based on two different Async method results

在我的数据服务中我有:

//Observables
currentTicket$: Observable<Ticket>;
ticketTypes$: Observable<Array<TicketType>>;
currentTicketSurvey$: Observable<TicketSurvey>;


//observers
private _ticketTypesObserver: any;
private _currentTicketSurveyObserver: any;
private _currentTicketObserver: any;

private _dataStore: {
    currentTicket: Ticket,
    ticketTypes: Array<TicketType>,
    currentTicketSurvey: TicketSurvey
}

constructor(private http: Http){
//set up observables
this.currentTicket$ = new Observable(observer=> this._currentTicketObserver = observer).share();
    this.ticketTypes$ = new Observable(observer=> this._ticketTypesObserver = observer).share();
    this.currentTicketSurvey$ = new Observable(observer=> this._currentTicketSurveyObserver = observer).share();


//init datastore
this._dataStore = {
        currentTicket: null,
        ticketTypes: [],
        currentTicketSurvey: null
    };
}



//Data Retrieval Methods

getTicketTypes() {
    if (this._dataStore.ticketTypes.length > 0) //if we already have ticket types, don't refresh.  Static Data.
        return;

    this.http.get('http://localhost:65421/tickets/GetTicketTypes/')
        .map(res => (<Response>res).json())
        .map((types: Array<any>) => {
            let result: Array<TicketType> = [];
            if (types) {
                types.forEach(ticketType => {
                    result.push(
                        new TicketType(
                            ticketType.Description
                            , ticketType.Id
                            , ticketType.IsDisplayed
                        ));
                });
            }

            return result;
        }).
        subscribe(
        data => {
            this._dataStore.ticketTypes = data;
            this._ticketTypesObserver.next(this._dataStore.ticketTypes);
        },
        err => {
            console.log(err);
        }
        );
}


getTicketSurvey(ticketId:string) {

    this.http.get('http://localhost:65421/tickets/GetTicketById/' + ticketId)
        .map(res => (<Response>res).json())
        .map((survey: TicketSurvey) => {
            let result: TicketSurvey = null;
            if (survey) {
                result = new TicketSurvey(
                    survey.id,
                    survey.ticketId,
                    survey.ticketTypeId
                );
            }

            return result;
        }).
        subscribe(
        data => {
            this._dataStore.currentTicketSurvey = data;
            this._currentTicketSurveyObserver.next(this._dataStore.currentTicketSurvey);
        },
        err => {
            console.log(err);
        }
        );
}


getTicketById(id:string) {
    this.http.get('http://localhost:65421/tickets/GetTicketById/' + id)
        .map(res => (<Response>res).json())
        .map((ticketRes: Ticket) => {
            let result: Ticket = null;
            if (ticketRes) {
                result = new Ticket(
                    //Set constructor values
                );
            }

            return result;
        }).
        subscribe(
        data => {
            this._dataStore.currentTicket = data;
            this._currentTicketObserver.next(this._dataStore.currentTicket);
        },
        err => {
            console.log(err);
        }
        );
}

我的组件有:

currTicket: Ticket;
ticketTypes: Array<TicketType>;
currTicketType: TicketType;
currTicketSurvey: TicketSurvey;


ngOnInit() {
    this.ticketDataService.currentTicket$.subscribe(cTicket => this.currTicket = cTicket);
    this.ticketDataService.ticketTypes$.subscribe(tTypes => this.ticketTypes = tTypes);
    this.ticketDataService.currentTicketSurvey$.subscribe(cSurvey => this.currTicketSurvey = cSurvey);

    this.load();
}

load()
{
    this.ticketDataService.getTicketById(this._routeParams.get('id'));
    this._ticketDataService.getTicketTypes();
    this._ticketDataService.getTicketSurvey(this._routeParams.get('id'));

    //////************ Need something here to set the current ticket type

    //this.ticketTypes.forEach((tType)=>{
    //    if(tType.id == this.currTicketSurvey.ticketTypeId)
    //    this.currTicketType = tType;
    //    return;
    //});

}

我遇到的问题是如何在组件中设置 currentTicketType?这取决于已加载的 currentTicketSurvey 和已加载的 ticketTypes。这些可能会或可能不会在我的代码的其他区域被一起调用,并且由于它们是异步调用,所以我不能在我调用服务后立即设置它。在淘汰赛中,我想我可以设置一个计算的可观察对象并完成它。我找不到 Angular 的等效项 2. 关于如何处理这种情况以在加载其他对象后设置 currentTicketType 的任何想法?

肯定经常出现。我看到的例子相似但不一样,说使用 defer 和 concatAll 但看起来会假设这些方法总是以相同的顺序或同时调用。我只是还没能拼凑出我要找的东西。

RxJS 提供了一组combining operators,我认为Observable.forkJoinObservable.merge可以满足您的需求。

  • Observable.forkJoin 将等待一组可观察对象接收到事件(每个):

    Observable.forkJoin([a,b]).subscribe(t=> {
      var firstResult = t[0];
      var secondResult = t[1];
    });
    
  • Observable.merge。收到 2 个结果时关闭流

    Observable.merge(obs1, obs2)
     .take(2)
     .subscribe({complete: () => { ... });
    

这个问题可以给你一些额外的提示: