我必须进行N次REST API调用并合并所有调用的结果,如果至少有一次调用失败(返回错误或超时),则会失败。我想使用RxJava,我有一些要求:
如果我想用一个线程发出所有请求,我需要一个异步Http客户端,不是吗?
谢谢
我建议使用可观察的代码来包装所有调用。
假设您有调用API的函数:
fun restAPIcall(request: Request): Single<HttpResponse>
你想打n次电话。我假设您希望使用一系列值调用它们:
val valuesToSend: List<Request>
Observable
.fromIterable(valuesToSend)
.flatMapSingle { valueToSend: Request ->
restAPIcall(valueToSend)
}
.toList() // This converts: Observable<Response> -> Single<List<Response>>
.map { responses: List<Response> ->
// Do something with the responses
}
因此,您可以从列表的元素中调用restAPI,并将结果作为列表。
另一个问题是重试。您说过要在达到单个上限时重试。这很棘手。我相信RxJava中没有现成的东西可以做到这一点。
retry(n)
,总共可以重试n次,但这不是您想要的。retry当{错误-
我以前没有使用过重试,但它似乎重试了整个可观察对象,这并不理想。
我的第一种方法是执行以下操作,即将每个元素的计数保存在字典或类似的内容中,并且只有在没有一个元素超过您的限制时才重试。这意味着您必须保留一个计数器,并在每次超出任何元素时进行搜索。
val counter = valuesToSend.toMap()
yourObservable
.map { value: String ->
counter[value] = counter[value]?.let { it + 1 }?: 0 // Update the counter
value // Return again the value so you can use it later for the api call
}
.map { restAPIcall(it) }
// Found a way to take yourObservable and readd the element if it doesn't exceeds
// your limit (maybe in an `onErrorResumeNext` or something). Else throw error
您可以使用Zip
运算符在所有请求结束后将它们压缩在一起,并在那里检查是否所有请求都成功
private Scheduler scheduler;
private Scheduler scheduler1;
private Scheduler scheduler2;
/**
* Since every observable into the zip is created to subscribeOn a different thread, it´s means all of them will run in parallel.
* By default Rx is not async, only if you explicitly use subscribeOn.
*/
@Test
public void testAsyncZip() {
scheduler = Schedulers.newThread();
scheduler1 = Schedulers.newThread();
scheduler2 = Schedulers.newThread();
long start = System.currentTimeMillis();
Observable.zip(obAsyncString(), obAsyncString1(), obAsyncString2(), (s, s2, s3) -> s.concat(s2)
.concat(s3))
.subscribe(result -> showResult("Async in:", start, result));
}
private Observable<String> obAsyncString() {
return Observable.just("Request1")
.observeOn(scheduler)
.doOnNext(val -> {
System.out.println("Thread " + Thread.currentThread()
.getName());
})
.map(val -> "Hello");
}
private Observable<String> obAsyncString1() {
return Observable.just("Request2")
.observeOn(scheduler1)
.doOnNext(val -> {
System.out.println("Thread " + Thread.currentThread()
.getName());
})
.map(val -> " World");
}
private Observable<String> obAsyncString2() {
return Observable.just("Request3")
.observeOn(scheduler2)
.doOnNext(val -> {
System.out.println("Thread " + Thread.currentThread()
.getName());
})
.map(val -> "!");
}
在这个例子中,我们只是确认结果,但您可以检查结果并在那里执行业务逻辑,而不是这样做。
您还可以考虑合并
或联系
。
您可以在此处查看更多示例https://github.com/politrons/reactive
我试图通过将多个改型api调用链接在一起来创建一个可观察的api。这些步骤是: 使用api调用获取json对象列表 对于列表中的每个对象,进行另一个api调用以获取有关该项目的更多详细信息 将从这个新的详细对象中获取的数据写入磁盘上的文件(列表中的每个项目都会出现这种情况) 最后返回一个单独对象的可观察性,该对象要求为之前的每个对象创建一个文件 这是我到目前为止所拥有的: 请有人确认我使用了正确的
haspart(x,FruitA) HasShape(x,Round) 我检索我的个人所属的每个类(在本例中,这应该包括SpeciesA)。 我根本不确定应该使用什么:我可以使用SWRL Species(?x)^HasPart(?x,Fruit)^HasShape(?x,“$round$”)还是应该使用Reasoner?
问题内容: 如何使用 java.net.URLConnection发出一个http请求? 问题答案: 首先先声明一下:发布的代码段都是基本示例。您需要处理琐碎的和,然后自己整理。 准备中 我们首先至少需要知道URL和字符集。参数是可选的,取决于功能要求。 查询参数的格式必须为,并由串联&。通常,您还可以使用指定的字符集对查询参数进行网址编码。 该只是为方便起见。当我需要String串联运算符+两次
问题内容: 我读了一些将jsons发布到服务器的示例。 有人说: OkHttp是Java提供的HttpUrlConnection接口的实现。它提供用于编写内容的输入流,并且不知道(或不在乎)内容的格式。 现在,我想用名称和密码的参数对URL进行常规发布。 这意味着我需要自己将名称和值对编码为流? 问题答案: 当前接受的答案已过期。现在,如果您想创建一个发布请求并向其中添加参数,则应该使用Mul
问题内容: 我有一个RESTful API,我已在EC2实例上使用Elasticsearch的实现公开了索引内容的语料库。我可以通过从终端机(MacOSX)运行以下命令来查询搜索: 如何使用或(不确定要使用哪个请求- 一直在使用urllib2,但听说请求更好…)将以上转换为API请求?我是否可以通过标题? 问题答案: 使用请求: 然后,根据您的API返回的响应类型,您可能需要查看或(或可能先检查)
我有一个RESTful API,我在EC2实例上使用Elasticsearch实现来索引内容语料库。我可以通过从我的终端(MacOSX)运行以下命令来查询搜索: 我如何使用python/requests或python/urllib2将上述内容转换为API请求(不确定应该选择哪一个-一直在使用urllib2,但听说请求更好?我是作为标题传递还是以其他方式传递?