【问题标题】:Chain of Observables.map doesn't wait for answer from rest requestObservables.map 链不等待来自休息请求的回答
【发布时间】:2017-10-26 12:01:59
【问题描述】:
return this.billingRest.getAccount()
        .map((response: any) => {
            this.logger.debug('initAccountAndPlans - after getAcccount');
            this.logger.debug("getAccount response", response);
            this.logger.debug('getAccount teamID=' + teamId +
                ' info=' + response.account.firstName + ' ' + response.account.lastName);
            this.account = response.account;
            return response;
        })
        .map( () => {
            return this.billingRest.getPlans()
                .map( (data) => {
                    this.logger.debug('getPlans result', data);
                    let plans = data;
                    if (this.utilService.isDefined(vm.usePilotPlan) && vm.usePilotPlan) {
                        plans = [];
                        plans.push(this.getPilotPlan());
                    }
                    logger.debug('getPlans=' +  JSON.stringify(data));
                    const screenPlans = [];
                    for (let i = 0; i < plans.length; i++) {
                        const plan = plans[i];
                        const screenPlan = this.transformPlanToView(plan);
                        screenPlans.push(screenPlan);
                    };
                    if (screenPlans.length === 0) {
                        return Observable.throw({msg: 'cannot find plans'});
                    }
                    vm.planOptions = screenPlans;
                    this.logger.debug('currentTeam', this.sessionService.getCurrentTeam());
                    return this.billingRest.getCurrentPlan(teamId);
                }).map((response: any) => {
                    const currentPlan = response.plan;
                    this.logger.debug('currentPlan skuCode=' + currentPlan.sku);
                    vm.currentPlan = currentPlan;
                    const currentOrder = response.order;
                    vm.currentOrder = currentOrder;

                    vm.nextBillDate = this.getNextBillDate(currentOrder);
                    if (! this.utilService.isDefined(response.creditCard)) {
                        vm.currentPaymentMethod = {};
                    } else {
                        vm.currentPaymentMethod = response.creditCard;
                        this.logger.debug('currentPaymentMethod id=' + vm.currentPaymentMethod.uuid); // BraintreePaymentMethodId
                    }
                    this.logger.debug('currentPaymentMethod', vm.currentPaymentMethod);
                    vm.plan = this.getPlanById(this.planOptions, currentPlan); // for checkout
                    return Observable.throw({});
                })
                .catch((error) => {
                    console.log("COŚ TU JEST NIE TAK" + error);
                    this.logger.exception('init-getPlans : Ajax Error')(error);
                    return Observable.throw(error);
                }).subscribe();
        })
        .catch( (response) => {
            this.logger.exception('initAccountAndPlans : Ajax Error')(response);
            return observable.throw(response);
        });
}

这是我的代码。如您所见,我有一个主链和一个 Observables.map 运算符的子串。到那一刻一切都很好

    return this.billingRest.getCurrentPlan(teamId);
            }).map((response: any) => {
                const currentPlan = response.plan; 

它不会触发,并且下一个 map 运算符不会等待响应,它会抛出错误 ' cannot read property of undefined ' 。它的行为就像它没有订阅,但实际上它有。当我使用 toPromise() 转换 get CurrentPlan 时,下一张地图不会等待结果,但该函数着火了。我不知道该怎么做,我不了解该功能的行为。

  getCurrentPlan (teamId) {
        console.log('GET CURRENTPLAN PRZED RESTEM')
        return this.http.get(this.restUrl + this.plansPrefix + '/' + teamId + '/getCurrentPlan', {observe: 'response'})
            .map( (response) => {
                console.log(" FULFILLED LOG ");
                return response.body;
            })
            .catch((response) => {
                console.log('GETCURRENTPLANNIEDZIALA');
                return Observable.throw(response);
            });
    };

【问题讨论】:

  • map 期望返回一个 value,而不是 observable,因此它不会订阅返回的 observable。尝试mergeMap(或switchMap,具体取决于您需要的行为)。
  • 我试过了,也没有用。它仍然没有触发。
  • 如果你的 map 函数调用另一个服务(例如返回另一个 observable 或 promise),那么使用mergeMap。如果它只是处理结果而不调用其他服务,请使用map
  • 是的,我明白这一点。但我的服务也返回一个值,如您所见,它是 respon.body。所以它仍然没有帮助。
  • 不,您的服务不返回值。它返回Observable&lt;Object&gt;,你应该试试同事的建议。

标签: angular rest rxjs reactivex


【解决方案1】:

在这个区块

  return this.billingRest.getCurrentPlan(teamId);
}).map((response: any) => {
  const currentPlan = response.plan;

我看不出 teamId 的来源。也许你的意思是this.teamId

也许,“无法读取未定义的属性”可能来自response.plan,因为响应未定义?

作为奖励,我认为这是

const screenPlans = [];
for (let i = 0; i < plans.length; i++) {
  const plan = plans[i];
  const screenPlan = this.transformPlanToView(plan);
  screenPlans.push(screenPlan);
};

可以这样写

const screenPlans = plans.map(plan => this.transformPlanToView(plan))

【讨论】:

    【解决方案2】:

    initAccountAndPlans(vm) {

        this.planOptions = [];
        this.plan = {}; // selected plan from planOptions
        this.currentPlan = {}; // currentPlan
        const teamId = this.sessionService.getCurrentTeam().uuid;
    
        /*          return billingRest.getPlans()
                  .then(function(data) {
                    console.log(data);
                  })
                  .catch(function(response) {
                    console.log(response);
                  })
         */
        return this.billingRest.getAccount()
            .map((response: any) => {
                this.logger.debug('initAccountAndPlans - after getAcccount');
                this.logger.debug("getAccount response", response);
                this.logger.debug('getAccount teamID=' + teamId +
                    ' info=' + response.account.firstName + ' ' + response.account.lastName);
                this.account = response.account;
                return response;
            })
            .map( () => {
                return this.billingRest.getPlans()
                    .map( (data) => {
                        this.logger.debug('getPlans result', data);
                        let plans = data;
                        if (this.utilService.isDefined(vm.usePilotPlan) && vm.usePilotPlan) {
                            plans = [];
                            plans.push(this.getPilotPlan());
                        }
                        logger.debug('getPlans=' +  JSON.stringify(data));
                        const screenPlans = [];
                        for (let i = 0; i < plans.length; i++) {
                            const plan = plans[i];
                            const screenPlan = this.transformPlanToView(plan);
                            screenPlans.push(screenPlan);
                        };
                        if (screenPlans.length === 0) {
                            return Observable.throw({msg: 'cannot find plans'});
                        }
                        vm.planOptions = screenPlans;
                        this.logger.debug('currentTeam', this.sessionService.getCurrentTeam());
                        return this.billingRest.getCurrentPlan(teamId);
                    })
                    .switchMap((response: any) => {
                        const currentPlan = response.plan;
                        this.logger.debug('currentPlan skuCode=' + currentPlan.sku);
                        vm.currentPlan = currentPlan;
                        const currentOrder = response.order;
                        vm.currentOrder = currentOrder;
    
                        vm.nextBillDate = this.getNextBillDate(currentOrder);
                        if (! this.utilService.isDefined(response.creditCard)) {
                            vm.currentPaymentMethod = {};
                        } else {
                            vm.currentPaymentMethod = response.creditCard;
                            this.logger.debug('currentPaymentMethod id=' + vm.currentPaymentMethod.uuid); // BraintreePaymentMethodId
                        }
                        this.logger.debug('currentPaymentMethod', vm.currentPaymentMethod);
                        vm.plan = this.getPlanById(this.planOptions, currentPlan); // for checkout
                        return Observable.throw({});
                    })
                    .catch((error) => {
                        console.log("COŚ TU JEST NIE TAK" + error);
                        this.logger.exception('init-getPlans : Ajax Error')(error);
                        return Observable.throw(error);
                    }).subscribe();
            })
            .catch( (response) => {
                this.logger.exception('initAccountAndPlans : Ajax Error')(response);
                return observable.throw(response);
            });
    }
    

    那是一个完整的函数,teamId是由sessionService.getCurrentTeam().uuid准备的。切换地图和合并地图不起作用。我不知道出了什么问题。

    【讨论】:

    • 我还是没有解决问题:(所以如果有人有想法,我会很喜欢的。
    猜你喜欢
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多