角度:HTTP调用完成之前,函数返回值

时间:2020-10-15 06:36:00

标签: angular ajax typescript return

我必须计算所选日期之间的工作日总数,并且我使用以下逻辑

this.businessDays = this.calcBusinessDays(this.startDate, this.endDate);

calcBusinessDays(d1: Date, d2: Date) {
        let date1 = new Date(d1);
        let date2 = new Date(d2);
        let oneDay = 1000 * 60 * 60 * 24;
        let difference = Math.floor((date2.getTime() - date1.getTime()) / oneDay);
        let businessDays = 0;
        let i: number;
        this.httpService
            .getHolidays(moment(date1).format('YYYY-MM-DD'), moment(date2).format('YYYY-MM-DD')) //start-date and end date are a part of query params in YYYY-MM-DD format.
            .subscribe((res: HttpResponse<HolidaysListInterface>) => {
                this.holidaysList = res.body.holidayDates;
                for (i = 0; i < difference; ++i) {
                    let day = date1.getDay();
                    let isHoliday = this.holidaysList.indexOf(moment(date1).format('YYYY-MM-DD')) != -1;
                    if (day != 0 && day != 6 && !isHoliday) {
                        ++businessDays;
                    }
                    date1.setDate(date1.getDate() + 1);
                }
            });
        return businessDays;
    }

现在,这里的问题是我每次都得到0作为返回值。该函数甚至在Http调用完成之前就返回该值。有什么解决方法?

1 个答案:

答案 0 :(得分:2)

因为这就是异步请求的工作方式。它们是异步执行的,而不管您指定的实际执行顺序。您可以进一步了解here

一种解决问题的方法是

任何直接依赖于HTTP调用响应的内容应该都应包含在订阅中

或换句话说

在需要回复的地方订阅

要记住的另一件事是,您无法同步返回异步变量(此处为businessDays

您还可以使用RxJS map运算符将响应转换为所需的格式

尝试以下

businessDays: any;

someFunc() {
    this.calcBusinessDays(this.startDate, this.endDate).subscribe(
        businessDays => this.businessDays = businessDays,
        error => {
            // always good practice to handle HTTP errors
        }
    );
}

calcBusinessDays(d1: Date, d2: Date): Observable<any> { // <-- return observable here
    let date1 = new Date(d1);
    let date2 = new Date(d2);
    let oneDay = 1000 * 60 * 60 * 24;
    let difference = Math.floor((date2.getTime() - date1.getTime()) / oneDay);
    let businessDays = 0;
    let i: number;
    return this.httpService
        .getHolidays(moment(date1).format('YYYY-MM-DD'), moment(date2).format('YYYY-MM-DD')) //start-date and end date are a part of query params in YYYY-MM-DD format.
        .pipe(
            map((res: HttpResponse<HolidaysListInterface>) => {
                this.holidaysList = res.body.holidayDates;
                for (i = 0; i < difference; ++i) {
                    let day = date1.getDay();
                    let isHoliday = this.holidaysList.indexOf(moment(date1).format('YYYY-MM-DD')) != -1;
                    if (day != 0 && day != 6 && !isHoliday) {
                        ++businessDays;
                    }
                    date1.setDate(date1.getDate() + 1);
                }
                return businessDays; // <-- return modified value here
            })
        );
}