如何在rxJava中返回值



我是rxJava的新手,它让我头晕目眩。基本上我用retrofit从youtube api中提取数据,它给出了Observable,用youtubeDataMapper,我把它映射到youtube Pojo对象,它包含String videoID。我的问题是,如何让这个方法返回那个字符串而不是Completable?

这是我的方法

@Override
  public Completable downloadVideoUrl(String query) {
    addSubscription(youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                              .map(youtubeDataMapper::map)
                              .subscribeOn(subscribeScheduler)
                              .observeOn(observeScheduler)
                              .subscribe());
    return Completable.complete();
}

你有两个选择:

  1. 让你的downloadVideoUrl返回Observable而不是Completable:

    首选方法:

    @Override
    public Completable downloadVideoUrl(String query) {
        return youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                .map(youtubeDataMapper::map)
                .subscribeOn(subscribeScheduler)
                .observeOn(observeScheduler);
    }
    

    注意这里缺少subscribe运算符。

    然后在你想要获取videoId的地方:

    downloadVideoUrl(query)
        .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                    @Override
                    public void onNext(String videoId) {
                        // do whatever you want with videoId
                    }
                });
    
  2. 使用toBlocking().first()

    这不是首选,因为你会阻塞当前的Thread直到Observable完成

    @Override
    public String downloadVideoUrl(String query) {
        return youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                .map(youtubeDataMapper::map)
                .subscribeOn(subscribeScheduler)
                .observeOn(observeScheduler)
                .toBlocking().first();
    }
    

首先,最好让Retrofit返回Single而不是Observable,因为你期望的是单个服务器响应(而不是一系列响应)。

其次,Completable.complete()是Completable的工厂方法,它什么都不做。所以你不需要它在这里。

关于字符串videoID,它取决于你打算用它做什么。另外,我不知道你的。addsubscription()在做什么。

我建议这样做:


class YourClass {
    private final CompositeSubscription compositeSubscription = new CompositeSubscription();
    // you must call compositeSubscription.clear() either in class .finalize() or on some UI lifecycle event
    void yourMethod() {
        final Single videoID = youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                .map(youtubeDataMapper::map)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        final Subscription subscription = videoID.subscribe(new SingleSubscriber() {                    
                    @Override
                    public void onSuccess(String value) {
                        // TODO: do whatever with the value
                    }
                    @Override
                    public void onError(Throwable error) {                         
                        // TODO: log and/or display error
                    }
                });
       compositeSubscription.add(subscription);
    }
}

相关内容

  • 没有找到相关文章

最新更新