2016-11-14 61 views
0

我有一个嵌套的forkjoin的问题,当我尝试订阅拉,它回来我的数据,但我可以看到,getitem3仍在运行。如何要等到所有的功能都完成之前,订阅如何等待嵌套forkjoin完成?

见例如

pull(id) { 
    return Observable.forkJoin(
    this.getitem1(id), 
    this.getitem2(id), 
    this.getitem3(id) 
); 
} 



getitem3(id) { 
    let url = 'https://host3/get/' + id; 
    let observableBatch = []; 

    return this.http.get(url).map(res => res.json()).map(data => { 
    data.posts.data.forEach((item) => { 
     observableBatch.push(this.getImageUrl(item.id)); 
    }) 
    return Observable.forkJoin(observableBatch); 
    }) 
} 


getitem2(id) { 
    let url = 'https://host2/get/' + id; 
    let observableBatch = []; 

    return this.http.get(url).map(res => res.json()).map(data => { 
    data.posts.data.forEach((item) => { 
    observableBatch.push(this.getImageUrl(item.id)); 
    }); 
    return Observable.forkJoin(observableBatch); 

    }); 
} 

getitem1(id) { 
    let url = 'https://host1/get/' + id; 
    let observableBatch = []; 

    return this.http.get(url).map(res => res.json()).map(data => { 
    data.posts.data.forEach((item) => { 
     observableBatch.push(this.getImageUrl(item.id)); 
    }); 
    return Observable.forkJoin(observableBatch); 
    }); 
} 

getImageUrl(id) { 
    let url = 'https://localhost/image/' + id; 
    return this.http.get(url).map(res => res.json()).map(data => { 
    console.log('done'); 
    }); 
} 
+0

在'getImageUrl(id)'方法中,您使用'subscribe',因此它调用了url。删除'subscribe'(所以它会返回一个可观察的)并重试。 – echonax

+0

我更改了订阅地图。我必须在我的getItem中订阅它吗? – kabus

+0

不,你应该订阅'拉(id)'方法,如果这是你唯一需要的。 – echonax

回答

2

我觉得你的方法getitemN()返回Observable <Observable<any>>。当你订阅你刚刚打电话给第一个可观察到的人时,你可以使用flatMap而不是map

.flatMap(data => { 
       data 
        .posts 
        .data 
        .forEach((item) => { 
         observableBatch.push(this.getImageUrl(item.id)); 
        }) 
       return Observable.forkJoin(observableBatch); 
      }) 

因此,在这种情况下,你将只得到Observable <any>

这里是有用的信息:http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http。 FlatMap位于“从属电话”部分。

+0

我无法对主要问题添加评论。 .map(data => {console.log('done');})。在这里你不会返回数据,所以在订阅者你什么也得不到。如果你想编写一些副作用,如登录到控制台,你可以使用do()方法。 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/do.md – Nikolai

+0

谢谢你,那正是我需要的。它现在按预期工作。 – kabus