如何从发出一个列表中的项目与RxJava延迟? [英] How to emit items from a list with delay in RxJava?

查看:466
本文介绍了如何从发出一个列表中的项目与RxJava延迟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的改造,以获得REST API的书签:

 公共接口BookmarkService {
    @GET(/书签)
    观察到与LT;名单<书签及GT;>书签();
}

现在我想从这个名单延迟发出的每个项目。

我没有类似的东西,以<一个href=\"http://stackoverflow.com/questions/25158245/how-to-emit-items-from-a-collection-with-delay-in-rxjava\">this在Java中,但 onCompleted 永远不会触发。

 私人观测&LT;书签及GT; getBookmarks(){
    返回getBookmarkService()。书签()
         .flatMap(新FUNC1&LT;名单,LT;收藏&gt;中可观察到的和LT;书签及GT;&GT;(){
            @覆盖
            公众可观察&LT;书签及GT;调用(列表&LT;书签及GT;书签){
                观察到与LT;书签及GT; resultObservable = Observable.never();
                的for(int i = 0; I&LT; bookmarks.size();我++){
                    清单&LT;书签及GT;块= bookmarks.subList(ⅰ,第(i + 1));
                    resultObservable = resultObservable.mergeWith(Observable.from(块).delay(1000 *我,TimeUnit.MILLISECONDS));
                }                返回resultObservable;
            }
        })
        .observeOn(AndroidSchedulers.mainThread());
}

我在做什么错了?

用法:

  mSwipeRefreshLayout.setRefreshing(真);
getBookmarks()
    .subscribe(新观察&LT;书签及GT;(){
        @覆盖
        公共无效onCompleted(){
            Timber.i(已完成);
            mSwipeRefreshLayout.setRefreshing(假);
        }        @覆盖
        公共无效onerror的(Throwable的E){
            Timber.i(错误:%s,e.toString());
            mSwipeRefreshLayout.setRefreshing(假);
        }        @覆盖
        公共无效onNext(收藏书签){
            Timber.i(收藏:%S,bookmark.toString());
            mBookmarksAdapter.addItem(书签);
        }
    });


解决方案

在您使用合并操作,onCompleted将是如果所有的观测值都完成呼叫。但 Observable.never()将永远不会完成。使用 Observable.empty()代替。

根据您的code,你想发出子列表延迟。子列表中只包含一个元素

你能做什么:flatmap您的清单,发出的每个项目。缓冲它来建立从项目的列表,然后使用一个延迟。

 私人观测&LT;书签及GT; getBookmarks(){
    返回getBookmarkService()。书签()
                               .flatMap((书签) - GT; Observable.from(书签)
      .buffer(1)
      .scan(新配对(0,NULL),(AC,值) - GT;双新(acu.index + 1,价值)
      .flatMap(对 - &GT; Observable.just(pair.value).delay(pair.index,秒))
                               .observeOn(AndroidSchedulers.mainThread());
}

它可能工作(未测试)

I'm using Retrofit to get bookmarks from REST API:

public interface BookmarkService {
    @GET("/bookmarks")
    Observable<List<Bookmark>> bookmarks();
}

Now I would like to emit each item from this list with delay.

I did something similar to this in Java, but onCompleted is never triggered.

private Observable<Bookmark> getBookmarks() {
    return getBookmarkService().bookmarks()
         .flatMap(new Func1<List<Bookmark>, Observable<Bookmark>>() {
            @Override
            public Observable<Bookmark> call(List<Bookmark> bookmarks) {
                Observable<Bookmark> resultObservable = Observable.never();
                for (int i = 0; i < bookmarks.size(); i++) {
                    List<Bookmark> chunk = bookmarks.subList(i, (i + 1));
                    resultObservable = resultObservable.mergeWith(Observable.from(chunk).delay(1000 * i, TimeUnit.MILLISECONDS));
                }

                return resultObservable;
            }
        })
        .observeOn(AndroidSchedulers.mainThread());
}

What I'm doing wrong?

Usage:

mSwipeRefreshLayout.setRefreshing(true);
getBookmarks()
    .subscribe(new Observer<Bookmark>() {
        @Override
        public void onCompleted() {
            Timber.i("Completed");
            mSwipeRefreshLayout.setRefreshing(false);
        }

        @Override
        public void onError(Throwable e) {
            Timber.i("Error: %s", e.toString());
            mSwipeRefreshLayout.setRefreshing(false);
        }

        @Override
        public void onNext(Bookmark bookmark) {
            Timber.i("Bookmark: %s", bookmark.toString());
            mBookmarksAdapter.addItem(bookmark);
        }
    });

解决方案

As you use a merge operation, onCompleted will be call if all Observables are completed. but Observable.never() will never complete. Use Observable.empty() instead.

According to your code, your want to emit sublist with delay. The sublist contains only one element

What you can do : flatmap your list, to emit each items. Buffer it to build a list from items, then use a delay.

private Observable<Bookmark> getBookmarks() {
    return getBookmarkService().bookmarks()
                               .flatMap((bookmarks) -> Observable.from(bookmarks)
      .buffer(1)
      .scan(new Pair(0, null), (ac, value) -> new Pair(acu.index + 1, value)
      .flatMap(pair -> Observable.just(pair.value).delay(pair.index, SECONDS)) 
                               .observeOn(AndroidSchedulers.mainThread());
}

it might work (not tested)

这篇关于如何从发出一个列表中的项目与RxJava延迟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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