How to use switchIfEmpty?

2019-08-20 21:41发布

I need to fetch data from DB. If it's empty, get data from server and insert it into database. Here is my code,

public Flowable<List<Data>> test() {
    return dataDao.allDatas()
           .switchIfEmpty(datas())
                .doOnNext(datas -> userStoreDao.insert(datas))
           );
}

public Flowable<List<Data>> datas() {
    return Flowable.zip(userFavoriteDatas(), userOtherDatas(),
        (favoriteDatas, otherDatas) -> {
            favoriteDatas.addAll(otherDatas);
            return favoriteDatas;
        });
}

public Flowable<List<Data>> userFavoriteDatas() {
    return userDatas()
        .map(UserDatas::favoriteDatas)
        .flatMapIterable(datas-> datas)
        .map(aLong -> new UserData(aLong, 1))
        .toList()
        .toFlowable();
}

public Flowable<List<Data>> userOtherDatas() {
    return userDatas()
        .map(UserDatas::otherDatas)
        .flatMapIterable(datas-> datas)
        .map(aLong -> new UserData(aLong, 1))
        .toList()
        .toFlowable();
}

private Flowable<Datas> userDatas() {
    return api
        .userDatas()
        .toFlowable()
        .share(); 
}

@GET("user/datas")
Single<Datas> datas();

It reaches second part when the first part returns empty result. datas() doesn't reached till the end while I'm running only the second part it works but combining with switchIfEmpty() it reaches to userDatas() and doesn't complete

I tried concat() as well with the same result.

1条回答
Evening l夕情丶
2楼-- · 2019-08-20 21:41

(From the comments):

If you use toList, that requires a finite stream. Based on the OP's feedback, the allDatas source was infinite but returned an empty List. The resolution was to apply at least take(1) to get exactly one response from allDatas and then optionally filter out the empty List so switchIfEmpty can switch over to the alternatives:

return allDatas.take(1).filter(list -> !list.isEmpty())
       .switchIfEmpty(datas())
       .doOnNext(datas -> userStoreDao.insert(datas));
查看更多
登录 后发表回答