如何组合多个Observable并在单个订阅中获得所有结果

时间:2016-04-05 20:35:23

标签: angular rxjs observable

我正在多次调用RESTful服务。每个电话都会给我一个结果。例如,它返回类似于以下内容的对象:

{
     results: {
          name: "Joe",
          age: 10,     
     }
}

我正在使用不同的请求参数对服务进行5次不同的调用,我只想在完成所有5次调用并返回其对象时将结果返回给我的程序。我想返回一个包含5个对象的数组的应用程序,如上面那个。

如何使用Observables在Angular 2中完成这项工作?

这是我之前尝试过的,但我无法弄清楚为什么它不起作用:

    getImage(imageUrl: string) {

        console.log("Fetching from " + imageUrl);

        return Observable.create((o) => {
            this.httpService.get(imageUrl)
            .map(res => {
                return res.json();
            })
            .map(res => res.photos.photo[0])
            .subscribe((result) => {
                console.log(this.generateImageUrl(result));
                o.next(this.generateImageUrl(result));
            });
        });
    }

    getImages(hashtags:string[]){
        var arrayOfObservables = [];
        for (var hashtag in hashtags){
            var url = this.flickrAPI.fetchImagesByTag + hashtags[hashtag];
            var query = this.getImage(url);
            arrayOfObservables.push(query);
        }
        console.log(arrayOfObservables);
        return Observable.forkJoin(arrayOfObservables, function(){
            console.log("Fork Join Done");
            return "from Fork Join with love";
        });
    }

然后订阅部分在这里发生

onSubmit() {
        // First, clear FeedItems
        this.feedItems = [];

        var tweets$ = this.twitterService.getTweets(this.hashtagInput);

        tweets$.subscribe((tweets) => {
            for (var i in tweets) {
                var hashtags = tweets[i].entities.hashtags;
                var flicks$ = this.flickrService.getImages(hashtags);
                this.subscribeToFlicks(flicks$, tweets[i]);
            }
        });
    }


    subscribeToFlicks(flicks$, tweet) {
        console.log("Here");
        flicks$.subscribe((results) => {
            console.log("Flickr Subscription:");
            console.log(results);

            var twitterItem = new TwitterData(tweet.user, tweet.text);
            var flickrItem = new FlickrData("null", results);

            var feedItem = new FeedItem(twitterItem, flickrItem);

            this.feedItems.push(feedItem);
        });
    }

1 个答案:

答案 0 :(得分:2)

实际上,您需要删除forkJoin方法的第二个参数:

getImages(hashtags:string[]){
    var arrayOfObservables = [];
    for (var hashtag in hashtags){
        var url = this.flickrAPI.fetchImagesByTag + hashtags[hashtag];
        var query = this.getImage(url);
        arrayOfObservables.push(query);
    }
    console.log(arrayOfObservables);
    return Observable.forkJoin(arrayOfObservables);
}

第二个参数对应resultSelector。它允许您(如果需要)在收到所有事件时创建forkJoin返回的结果。如果未指定,则会将结果作为数组返回。

订阅返回的observable:

getImages().subscribe(() => {
  console.log("Fork Join Done");
});

因为一个observable是懒惰的,没有订阅就不会执行任何事情......

修改

您可以通过以下方式更新étiAge方法:

    getImage(imageUrl: string) {

        console.log("Fetching from " + imageUrl);

        return this.httpService.get(imageUrl)
            .map(res => {
                return res.json();
            })
            .map(res => res.photos.photo[0])
            .map(res => this.generateImageUrl(res));
    }