Observable 嵌套循环

Observable nested with loop

我想创建一个嵌套的可观察对象来保存一个与标签相关的内容。首先保存内容和 return 内容 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 ---

看起来它几乎同时进入了方法。我怎样才能让 savetag 等待一个保存完成然后再做下一个?

我的方法是使用递归方法:

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 完成其操作后才开始。

尝试这样的事情:

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 运算符,但我不知道。

您也可以稍微更改一下设计。您可以将给定类别的所有标签发送到后端端点,并在那里处理保存标签。您可以完全控制您希望如何保存它们。