需要帮助了解如何正确实现订阅

时间:2016-11-09 09:44:16

标签: angular typescript

方案

对于我的项目,我需要对http服务进行两次调用,我在一个函数中调用它们:getData()。我需要两个Arrays的信息来解析它到另一个对象。

一个服务电话叫

  • getObjectData()

在此功能中,我将调用与ID对应的服务。我将使用Objects获取一个数组。我需要Object Id和这个对象的名称。

  • getSensorData()

每个ObjectId也有一个带有SensorData的DeviceID,所以从逻辑上讲,我为每个ID做一个for循环,以获取相应的数据。数据是一个数组,因此我需要sensorData[]中每个sensorData的信息。

objects: TableData[];
otamObjects: OtamObject[];
sensorData: SensorData[];

总而言之,我希望TableData[]填充数据,然后我可以用它来填充表格。

代码:

我在component.ts中有以下代码

getData(): void {
    this.objects = new Array<TableData>();
    this.service.getObjectData(1)
        .subscribe(otamObject => {
            this.otamObjects = otamObject;
            console.log(JSON.stringify(this.otamObjects));
            for (let item of this.otamObjects) {
                console.log(JSON.stringify(item));
                var object = new TableData();
                object.Name = item.Name;
                object.ObjectId = item.OtamObjectId;
                (console.log('Create a new object' + JSON.stringify(object)));
                this.service.getSensorData(item.DeviceId)
                    .subscribe(response => {
                        for (let item of response) { // Forgive me for the following hard coded strings.                            
                            if (item.Key === 'Latitude') {
                                object.Latitude = item.Value;
                            }
                            if (item.Key === 'Longitude') {
                                object.Longitude = item.Value;
                            }
                            if (item.Key === 'Battery') {
                                object.Latitude = item.Value;
                            }
                            if (item.Key === 'Charging') {
                                object.Charging = item.Value;
                            }
                            if (item.Key === 'LocationType'){
                                if (item.Value === '1'){
                                    object.LocationType = "GPS";
                                } else {
                                    object.LocationType = "GSM";
                                }
                            }
                            object.LastActvity = item.CreatedDate;
                            console.log('Second for loop has finished: ' 
                            + JSON.stringify(object));                              
                        }
                        this.objects.push(object);
                        console.log("Second For loop has finished, pushing this object: " + JSON.stringify(object) + 
                        " to the array of objects: " + JSON.stringify(this.objects))
                    }, error => { console.log(<any>error); })
            }
            console.log('End of the first for loop, with data in Objects: ' + JSON.stringify(this.objects));
        },
        error => {
            console.log(<any>error);
        }
        );
};

在我打电话的服务中:

getObjectData(companyId: number): Observable<OtamObject[]> {
    return this.http.get(this.actionUrl + "otamObject/" + companyId, this.headers)
        .map((response: Response) => <OtamObject[]>response.json())
        .catch(this.handleError);
}

getSensorData(deviceId: number): Observable<SensorData[]> {
    return this.http.get(this.actionUrl + "sensorData/deviceId/" + deviceId, this.headers)
        .map((response: Response) => <SensorData[]>response.json())
        .catch(this.handleError);
}

问题

我提出这个问题的原因是,现在,正如您在输出enter image description here中看到的那样,第一个for循环在其他所有内容之前完成,但这不是我想要的。我想要有三个对象然后他需要为每个对象做第二个for循环。

我不完全理解如何解决这个问题,在任何其他编程语言中,第一个for循环应该在最后一个之前等待,所以它只会这样做,但因为我得到了它,它只是完成循环。我知道它与第二个订阅有关。无论如何,处理这个问题的正确方法是什么。

1 个答案:

答案 0 :(得分:0)

for循环不会等待订阅完成。因为可观察的函数是异步运行的。可能想使用类似var root = JSON.parse('{ "id": "chapter", "chapterName": "Example Chapter", "stages": [{ "id": "stage", "stages": [{ "id": "stage", "stages": [], "reviewSets": [{ "id": "reviewset-1", "yettoanswer": 2, "answered": 4 }] }], "reviewSets": [{ "id": "reviewset-2", "yettoanswer": 3, "answered": 5 }, { "id": "rewviewset-3", "yettoanswer": 6, "answered": 0 }] }, { "id": "stage", "stages": [{ "id": "stage", "stages": [], "reviewSets": [{ "id": "reviewset-4", "yettoanswer": 0, "answered": 8 }, { "id": "reviewset-5", "yettoanswer": 4, "answered": 4 }] }], "reviewSets": [{ "id": "reviewset-6", "yettoanswer": 1, "answered": 2 }, { "id": "reviewset-7", "yettoanswer": 6, "answered": 4 }] }], "reviewSets": [{ "id": "reviewset-8", "yettoanswer": 0, "answered": 2 }, { "id": "reviewset-9", "yettoanswer": 1, "answered": 2 }] }'); sumAnswers(root); console.log(root); // `JSON.stringify(root)` if you need a JSON result function sumAnswers(stage) { // introduce new properties to the current stage stage.yettoanswer = 0; stage.answered = 0; // sum up the values of reviewSets stage.reviewSets.forEach(function(child) { stage.yettoanswer += child.yettoanswer; stage.answered += child.answered; }); // call this function for each stage and then // sum up the values of stages stage.stages.forEach(function(child) { sumAnswers(child); stage.yettoanswer += child.yettoanswer; stage.answered += child.answered; }); }库的东西为for循环添加回调。