Observable与循环嵌套

时间:2016-09-23 08:17:28

标签: angular angular2-services angular2-observables

我想创建一个嵌套的observable来保存一个与标签相关的内容。首先保存内容并返回内容id以保存标签,内容id为外键,就像服务在循环中同时发送数据一样。 (后端日志运行pararel)我怎么能让它等到完成下一个

component.ts

save(){
  this.contentService.savecontent(this.content_input) // save content
     .subscribe(
     data => { this.listContentData = data }, // return data to get content id
     error => { error = error },
     () => {
        this.savetag(this.listContentData); // save tag
     });
}

savetag(listcontentdata): void {
   // listdraftCategories is a list of tag
    for (var i = 0; i < this.listdraftCategories.length; i++) {  
        this.tagService.savetagwithcontent(this.listdraftCategories[i], listcontentdata)
            .subscribe(
            data => { data = data },
            error => { },
            () => {
            });
    }
}

service.ts

savecontent(contentObj: any): Observable<any> {

    contentObj = JSON.parse(contentObj);

    let body = JSON.stringify(

        {
            "token": "test",
            "content": {
                "contentName": contentObj.itemName // contentId will be autoincrement in backend
                }
            }
        }
    );

    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.host + this.url_content + this.url_save, body, options)
        .map(res => this.extractData(res))
        .catch(this.handleError);
}

savetagwithcontent(tagObj: any, contentObj: any): Observable<any> {

    console.log("obj", contentObj);

    let body = JSON.stringify(
        {
            "token": "test",
            "content": {

                "fkTag": {
                    "tagId": tagObj.tagId
                },
                "fkContent": {
                    "contentId": contentObj.responseObject[0].contentId
                }

            }
        }
    );

    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.host + this.url_tag_has_content + this.url_save, body, options)
        .map(res => this.extractData(res))
        .catch(this.handleError);
}

后端日志(保存带内容的标签)

--- start save tag with content ---
--- start save tag with content ---
--- content id : 1 tag id: 1 ---
--- content id : 1 tag id: 2 ---
--- end save tag with content ---
--- end save tag with content ---

看起来它几乎同时进入了方法。如何设置保存标签等待一个保存完成然后执行下一个保存?

2 个答案:

答案 0 :(得分:1)

我会采用递归方法:

savetag(listcontentdata:any, index = 0): void {
    if(index >= this.listdraftCategories.length){
        return;
    }
    // listdraftCategories is a list of tag
    this.tagService.savetagwithcontent(this.listdraftCategories[index], listcontentdata)
        .subscribe(
        data => { 
            data = data;
            this.savetag(listcontentdata, index +1);
        },
        error => { },
        () => {
        });

}

这样,savetag方法的下一次迭代只会在当前observable完成其操作后启动。

答案 1 :(得分:1)

尝试这样的事情:

const observables = [];
for (var i = 0; i < this.listdraftCategories.length; i++) {  
  observables.push(this.tagService.savetagwithcontent(this.listdraftCategories[i], listcontentdata));
}

let i = 0;
let finished = true;
while(i < observables.length) {
  if (finished) {
    finished = false;
    observables[i].subscribe(
      data => {
        finished = true;
        i++;
        data = data 
      },
      error => { },
      () => {});
  }
}

可能有一些漂亮的rxjs运算符,但我不知道。

你也可以稍微改变你的设计。您可以向后端端点发送给定类别的所有标记,并在那里处理保存标记。您可以完全控制如何保存它们。