【问题标题】:How to set a result based on two different Async method results如何根据两个不同的 Async 方法结果设置结果
【发布时间】:2016-02-18 23:07:42
【问题描述】:

在我的数据服务中,我有:

//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 和已加载的票证类型。这些可能会或可能不会在我的代码的其他区域一起调用,并且由于它们是异步调用,我不能在我在服务上调用它们之后立即设置它。在淘汰赛中,我想我可以设置一个计算出的 observable 并完成它。我找不到 Angular 2 的等价物。关于如何处理这种情况以在加载其他对象后设置 currentTicketType 的任何想法?

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

【问题讨论】:

    标签: angular rxjs angular2-services


    【解决方案1】:

    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: () => { ... });
      

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

    【讨论】:

    • 即使我的代码无法正常工作,我也会将此标记为答案。我认为我的代码不起作用的原因与此无关。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    相关资源
    最近更新 更多