RxJava和基于游标的RESTful分页 [英] RxJava and cursor based RESTful pagination

查看:139
本文介绍了RxJava和基于游标的RESTful分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spotify API,希望使用RxJava链接一些分页的结果. Spotify使用基于游标的分页,因此来自@lopar 的解决方案将不起作用.

I'm working with the Spotify API and am hoping to chain a few paginated results using RxJava. Spotify uses cursor based pagination, so solutions like the one from @lopar will not work.

响应来自此调用,看起来像这个(假设有50个items):

The response is from this call and looks something like this (imagine there are 50 items):

{
  "artists" : {
    "items" : [ {
      "id" : "6liAMWkVf5LH7YR9yfFy1Y",
      "name" : "Portishead",
      "type" : "artist"
    }],
    "next" : "https://api.spotify.com/v1/me/following?type=artist&after=6liAMWkVf5LH7YR9yfFy1Y&limit=50",
    "total" : 119,
    "cursors" : {
      "after" : "6liAMWkVf5LH7YR9yfFy1Y"
    },
    "limit" : 50,
    "href" : "https://api.spotify.com/v1/me/following?type=artist&limit=50"
  }
}

现在,通过改型,我得到了前50个结果:

Right now, I'm getting the first 50 results like this, using retrofit:

public class CursorPager<T> {
    public String href;
    public List<T> items;
    public int limit;
    public String next;
    public Cursor cursors;
    public int total;

    public CursorPager() {
    }
}

public class ArtistsCursorPager {
    public CursorPager<Artist> artists;

    public ArtistsCursorPager() {
    }
}

然后

public interface SpotifyService  {

    @GET("/me/following?type=artist")
    Observable<ArtistsCursorPager> getFollowedArtists(@Query("limit") int limit);

    @GET("/me/following?type=artist")
    Observable<ArtistsCursorPager> getFollowedArtists(@Query("limit") int limit, @Query("after") String spotifyId);

}

mSpotifyService.getFollowedArtists(50)
        .flatMap(result -> Observable.from(result.artists.items))
        .flatMap(this::responseToArtist)
        .sorted()
        .toList()
        .subscribe(new Subscriber<List<Artist>>() {
            @Override
            public void onNext(List<Artist> artists) {
                callback.onSuccess(artists);
            }
            // ...
        });

我想返回callback.success(List<Artist>)中的所有(在这种情况下为119个)艺术家.我是RxJava的新手,所以不确定是否有 smart 方法.

I'd like to return all (in this case 119) artists in callback.success(List<Artist>). I'm new to RxJava, so I'm unsure if there is a smart way to do this.

推荐答案

递归解决方案的唯一问题是堆栈溢出问题.一种无需递归的方法是

The only problem with the recursive solution is the stack over flow problem. A way to do it without recursion is

Observable<ArtistsCursorPager> allPages = Observable.defer(() ->
{
    BehaviorSubject<Object> pagecontrol = BehaviorSubject.create("start");
    Observable<ArtistsCursorPager> ret = pageControl.asObservable().concatMap(aKey ->
    {
        if (aKey != null && aKey.equals("start")) {
            return Observable.getFollowedArtists(50).doOnNext(page -> pagecontrol.onNext(page.cursors.after));
        } else if (aKey != null && !aKey.equals("")) {
            return Observable.getFollowedArtists(50,aKey).doOnNext(page -> pagecontrol.onNext(page.cursors.after));
        } else {
            return Observable.<ArtistsCursorPager>empty().doOnCompleted(()->pagecontrol.onCompleted());
        }        
    });
    return ret;
});

请参见此问题的解决方法.

这篇关于RxJava和基于游标的RESTful分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆