如何在RxJava/RxAndroid中多次重复相同的网络请求(不同的参数)?

如何在RxJava/RxAndroid中多次重复相同的网络请求(不同的参数)?,java,android,rx-java,Java,Android,Rx Java,因此,我有一个/downloadAPI,它返回一个通用的对象(基于其自身参数的索引号),然后我必须将其保存到数据库中,如果事务成功,我必须增加索引并再次重复相同的过程,否则重试() 我需要重复50次 如何使用Rx Java实现此过程? 我现在被卡住了。任何帮助都会很棒。谢谢。可观测范围(1,50) Observable.range(1, 50) .flatMap(index -> // for every index make new request ma

因此,我有一个
/download
API,它返回一个通用的
对象
(基于其自身参数的索引号),然后我必须将其保存到数据库中,如果事务成功,我必须增加索引并再次重复相同的过程,否则
重试()

我需要重复50次

如何使用Rx Java实现此过程? 我现在被卡住了。任何帮助都会很棒。谢谢。

可观测范围(1,50)
Observable.range(1, 50)
    .flatMap(index ->      // for every index make new request
        makeRequest(index) // this shall return Observable<Response>
            .retry(N)      // on error => retry this request N times
    )
    .subscribe(response -> saveToDb(response));
.flatMap(索引->//为每个索引发出新请求 makeRequest(index)//这将返回可观察的 .retry(N)//on error=>重试此请求N次 ) .subscribe(response->saveToDb(response));
对评论的回答(仅在先前的回复保存到db后提出新请求):

可观测范围(1,50)
.flatMap(索引->//为每个索引发出新请求
makeRequest(index)//这将返回可观察的
.retry(N)//on error=>重试此请求N次
.map(response->saveToDb(response)),//保存并报告成功
1//将并发限制为单个请求保存
)
.subscribe();

如果我理解正确,这段代码应该为您指明正确的方向

        BehaviorSubject<Integer> indexes = BehaviorSubject.createDefault(0);
        indexes.flatMap(integer -> Observable.just(integer)) // download operation
               .flatMap(downloadedObject -> Observable.just(integer)) // save operation
               .doOnNext(ind -> indexes.onNext(ind + 1))
               .subscribe(ind -> System.out.println("Index " + ind));
BehaviorSubject index=BehaviorSubject.createDefault(0);
index.flatMap(integer->Observable.just(integer))//下载操作
.flatMap(下载对象->可观察的.just(整数))//保存操作
.doOnNext(ind->index.onNext(ind+1))
.subscribe(ind->System.out.println(“索引”+ind));
发生的情况是:

  • BehaviorSubject是整个工作的发起人,它提供索引 到链条上
  • 第一个平面图是进行下载操作的地方
  • 第二个平面图是将其保存到DB的位置
  • 在doOnNext你必须 向主题发出onNext或onComplete以继续或完成 处理。(这可以在订阅服务器中完成)
  • 请记住在
    onNext
    中添加停止条件,以避免以无限循环结束

    我需要重复50次

    您可以使用
    range
    运算符处理每个发出的Int

    如果交易成功,我必须增加索引

    在这种情况下,您需要使用
    concatMap
    操作符。它按顺序处理每个
    可观察的

    Observable<Response> makeRequest(int i) {...}
    
    Completable saveToDb(Response response) {...}
    
    Observable.range(1, 50)
        .concatMap(i -> makeRequest(i)
                            //I assume that you save your response to DB asynchronously
                            //if not - use doOnNext operator instead of flatMapCompletable
                            .flatMapCompletable(response -> saveToDb(response)
                            .toObservable())
        .retry()
        ...
    
    可观察的makeRequest(inti){…}
    可完成的saveToDb(响应){…}
    可观测范围(1,50)
    .concatMap(i->makeRequest(i)
    //我假设您将响应异步保存到DB
    //如果不是-使用doOnNext运算符而不是flatMapCompletable
    .flatMapCompletable(响应->保存TODB(响应)
    .toObservable())
    .重试()
    ...
    
    我尝试了你的答案,它似乎立即调用了另一个API。有没有办法等待结果,将其保存到db,然后,只有在那时,调用一个新的API???@gubaju,以实现将保存操作移动到请求管道中,并将
    flatMap
    并发性限制为1。那么我如何传递从第一个平面接收到的值呢映射(API)到我的第二个flatmap(db)。它是自动传递的,在这里我将这些变量命名为integer,但事实上,第一个flatmap返回对象,即用户,它成为第二个flatmap的输入。我在这段代码中遇到了与@Yaroslav.makeRequest()类似的问题立即被调用。只有在成功保存数据库后才会调用它。
    concatMap
    为每个
    可观察的
    等待
    onComplete
    。在我的示例中,它是组合的
    可观察的
    ,包含
    makeRequest
    saveToDb
    。您的实现似乎有问题。但是我的答案是修复代码格式。请发布您的代码。我认为它更可能面临HTTP错误,而不是事务错误。因此,HTTP层更需要重试机制。
    Observable<Response> makeRequest(int i) {...}
    
    Completable saveToDb(Response response) {...}
    
    Observable.range(1, 50)
        .concatMap(i -> makeRequest(i)
                            //I assume that you save your response to DB asynchronously
                            //if not - use doOnNext operator instead of flatMapCompletable
                            .flatMapCompletable(response -> saveToDb(response)
                            .toObservable())
        .retry()
        ...