我正在尝试通过将多个改装api调用链接在一起来创建一个observable。步骤是:
这是我到目前为止所做的:
public static Observable<DownloadedFiles> downloadFiles() {
DownloadedFiles downloadedFiles = new DownloadedFiles();
Observable.create(subscriber -> {
return getRestService().getObjectList()
.flatMapIterable(objects -> objects)
.flatMap(objectLimited -> getRestService().getObject(objectLimited.getPath()))
.doOnNext(objectFull -> {
try {
File file = new File();
// Extract data from objectFull and write new file to disk
// ...
} catch (IOException e) {
subscriber.onError(e);
}
downloadedFiles.putFile(file);
})
.toList()
.map(objects -> downloadedFiles)
.finallyDo(() -> {
subscriber.onNext(downloadedFiles);
subscriber.onCompleted();
});
});
}
@GET("/api/...")
Observable<List<Object>> getObjectList();
@GET("/api/.../{path}")
Observable<Object> getObject(@Path("path") String path);
有人可以确认我使用了正确的操作符。谢谢。
答案 0 :(得分:2)
编辑:删除了Observable.create,改造已经为你做了一个可观察的,你只需要改造它。
编辑2:你也不需要对subscriber.onError做任何事情,如果抛出错误,它将自己调用subscriber.onError。
非常好,不确定为什么你选择了flatmap observable。我宁愿做平面图到Observable :: from,也值得添加。基本上我会将1个事物映射到很多,然后做一些动作,将许多东西收回到一个,然后在收集所有发出的物品后订阅那个。
public static Observable<DownloadedFiles> downloadFiles() {
return getRestService().getObjectList()
.flatMap(Observable::from)
.flatMap(objectLimited -> getRestService().getObject(objectLimited.getPath()))
.doOnNext(objectFull -> {
try {
File file = new File();
// Extract data from objectFull and write new file to disk
// ...
} catch (IOException e) {
new IOException(e);
}})
.collect(() -> new DownloadFiles<>(), (files, object) -> { files.add(object});
答案 1 :(得分:0)
我认为这样的一些应该适合你。您可以使用REST服务中的Observable映射到每个DownloadedFiles,而不是拉入Subject以将其发送到DownloadedFile:
public static Observable<DownloadedFile> downloadFiles() {
final Observable<Observable<FullObject>> observable = getRestService().getObjectList()
.flatMapIterable(objects -> objects)
.map(objectLimited -> getRestService().getObject(objectLimited.getPath()));
return Observable.mergeDelayError(observable)
.map(fullObject -> {
try {
File file = new File("path");
// Extract data from objectFull and write new file to disk
// ...
return new DownloadedFile();
} catch (IOException e) {
throw OnErrorThrowable.from(OnErrorThrowable.addValueAsLastCause(e, fullObject));
}
});
}
如果要在传播任何错误之前发出成功保存的文件,您可能需要考虑使用mergeDelayError(map())而不是flatMap。