Angular2:嵌套在循环内订阅第二个订阅

时间:2017-08-04 22:07:07

标签: angular http request angular2-observables angular2-http

我只用Angular2一周了!

基本上有2个API调用。

  1. 第一个API调用给我一个json对象的数组(queryResults)。 (第一次订阅)
  2. 在视图中显示该数组。
  3. 遍历(queryResults)数组并从每个数组元素中选择一个特定的键:值对(queryResults [i] .oldLastSeen)。
  4. 将该值(oldLastSeen)作为请求参数传递给另一个获取字符串(newLastSeen)的API。 (第二次订阅)
  5. 用queryResult
  6. 中的newLastSeen替换oldLastSeen

    由于Observables的异步特性,问题出现在第5步。我无法访问内部订阅内的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.")
                    );
            }
        }
      }
    

    自从2天以来一直在敲我的头,遇到了flatMap,switchMap等。但对他们的使用情况高度怀疑。

    更新:工作代码:

    我遵循了Bryan的反馈,并对他建议的代码进行了一些修改。这对我有用:

    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
          }); 
    

1 个答案:

答案 0 :(得分:1)

通常,如果您有嵌套订阅,那么您将处理可以改进的反模式。我还没有找到一个令人信服的案例来使用它。我不确定对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);

}

逐一拍摄:

  1. 您收到了查询

  2. 您将结果设置为视图。功能纯粹主义者会说这样做是不好的做法,因为它使用副作用,但无论如何。我不是纯粹主义者。

  3. 这个很棘手,但你将结果展平成一个可观察的流。你可以从结果数组中创建一个observable,flatmap一个接一个地发出它们,你也可以在这里使用jsut .mergeAll()。这是循环结果的一种更具反应性的方式。

  4. 过滤掉您对

  5. 不感兴趣的项目
  6. 您的&#34;操作&#34;的占位符行,可能是map或do,很难说不知道所需的效果。也可能只是在switchMap中可行,但指出风格并保持运营商的简洁。

  7. switchMap进入新的observable,switchMap将订阅内部observable并发出结果,这个键的关键是switchMap的第二个参数,它允许你组合来自内部和外部observable的项目。这里我们只是将它们放入一个数组中并发出两个值的数组

  8. 重置订阅中的项目。这里唯一有趣的是使用typescript语法,它可以让你为数组中的项命名,因为你知道你已经获得了2个项目的数组。

相关问题