我和安格拉在一起才一周!
基本上有两个api调用。
第一个api调用给我一个json对象数组(queryresults)。(首次认购)
在视图中显示该数组。
循环遍历(queryresults)数组并从每个数组元素(queryresults[i].oldlastseen)中选择一个特定的键:值对。
将该值(oldlastseen)作为请求参数传递给另一个api,该api为我获取一个字符串(newlastseen)。(第二次认购)
在QueryResult中用NewLastSeen替换OldLastSeen
问题出现在第五步,因为观测的异步性。我无法访问内部订阅中的queryResults[i].oldLastSeen,基本上未定义。因此lastseen不会更新。
从调用getLastSeen()开始,
代码如下:

temp: any[];
rows: any[];

getLastSeen() {
    this._someService.getQueryResults(this.query)
      .subscribe(queryResults => {
        this.rows = queryResults;
        this.updateLastSeen(this.rows);
      });
}

private updateLastSeen(rows) {
    this.temp = rows; //temp: any[];
    for(var i=0; i<this.temp.length; i++) {
        if(this.temp[i].id != null || this.temp[i].oldLastSeen != null) {
            //Some operations here
            this._someService.getNewLastSeen(this.temp[i].oldLastSeen)
                .subscribe(
                    newLastSeen => {
                        this.rows[i].oldLastSeen = newLastSeen; //This doesnot happen!
                    },
                    error => alert(error),
                    () => console.log("Finished.")
                );
        }
    }
  }

两天来我的头撞了一下,碰到了flatmap、switchmap等,但对它们的使用非常怀疑。
更新:工作代码:
我跟踪了布赖恩的反馈,并对他建议的代码做了一些修改。以下是对我有用的:
this._someService.getQueryResults(this.query)
      .do(qr => {this.rows = qr;})
      .flatMap(queryResults => Observable.from(queryResults))
      .filter(queryItem => queryItem["id"] != null || queryItem["oldLastSeen"] != undefined)
      .do(queryItem => { // did some operations/ manipulations here})
      .mergeMap(queryItem => this._someService.getNewLastSeen(this.queryItem["oldLastSeen]),
           (queryItem, newLastSeen) => [queryItem, newLastSeen])
      .subscribe(([queryItem, newLastSeen]) => {
        queryItem.oldLastSeen = newLastSeen
      });

最佳答案

一般来说,如果您有嵌套的订阅,则处理的是可以改进的反模式。我还没有找到一个令人信服的理由来使用它。我不知道对flatmap或switchmap持怀疑态度意味着什么,但它们是非常有用的操作符,尤其是switchmap。如果没有工具包中的switchmap,您将无法做更多超出rxjs基础的工作。

getLastSeen() {
    this._someService.getQueryResults(this.query)
      .do(qr => this.rows = qr;)
      .flatMap(queryResults => Observable.from(queryResults))
      .filter(queryItem => queryItem.id !== null || queryItem.oldLastSeen !== null)
      // you can insert a map or do operator here to accomplish the operations you mention, depending on what they are, or you can possibly just do them inside switchMap
      .switchMap(queryItem => this._someService.getNewLastSeen(queryItem.oldLastSeen),
           (queryItem, newLastSeen) => [queryItem, newLastSeen])
      .subscribe(([queryItem, newLastSeen]) => queryItem.oldLastSeen = newLastSeen);

}

一件一件拿:
你得到你的查询
将结果设置为视图。功能纯粹主义者会说,在这里这样做是不好的做法,因为它使用了副作用,但无论如何。我不是一个纯粹主义者。
这是一个棘手的问题,但你正在将你的结果扁平化为一个可观察的流。您可以从结果数组中创建一个observate,flatmap会一个接一个地发出它们,这里也可以使用jsut used.mergeall()。这是一种比较被动的循环结果的方式。
筛选出你不感兴趣的项目
为你的“操作”占位符行,可能是地图或做,很难说不知道想要的效果。也可能只是在switchmap内部可行,但点的样式和保持操作简洁。
将switchmap转换成新的observate,switchmap将订阅内部observate并发出结果,关键是switchmap的第二个参数,它允许您将来自内部observate和外部observate的项组合起来。在这里,我们将它们放入一个数组中,并发出两个值的数组
重置订阅中的项。这里唯一有趣的是使用typescript语法,因为您知道您得到的数组包含2个项,所以可以命名数组中的项。

关于angular - Angular2:嵌套订阅,循环内包含第二个订阅,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45516125/

10-12 13:38