How to emit items from a list with delay in RxJava?

别说谁变了你拦得住时间么 提交于 2019-12-22 04:46:10

问题


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

回答1:


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)



来源:https://stackoverflow.com/questions/28179199/how-to-emit-items-from-a-list-with-delay-in-rxjava

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!