当 Maybe 为空时终止流而不抛出异常
Terminate stream when Maybe is empty without throwing the exception
我有以下通过 REST 响应式调用的方法:
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.switchIfEmpty(Maybe.fromAction(() -> new Result(new JsonObject()))) //empty result
.toSingle()
.flatMap(value -> repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()));
}
我可以用 Maybe.error(new Exception())
终止流,但调用方将收到我不想发送的错误响应。
当外部服务returns Maybe.empty()
时,是否可以return Single<Result>
(在中间终止流)而不恢复主流(来自toSingle()
行)?
更新
我尝试按照@akarnokd 的建议将flatMap
+ map
块放在switchIfEmpty
之前。首先,我将它们提取到单独的方法中:
private Single<Result> persistValue(Value value) {
return repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()));
}
并在主管道中使用此方法:
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.map(this::persistValue)
.switchIfEmpty(Maybe.fromAction(() -> new Result(new JsonObject()))) //empty result
.toSingle()
.cast(Result.class);
}
这一次,当 Maybe.empty()
被 return 编辑时,我得到:
Operation could not be performed as entity stream did not return any results: The MaybeSource is empty
java.util.NoSuchElementException: The MaybeSource is empty
因为它的空状态被传递给了persistValue
方法。也许我没明白把 map
放在 Maybe.empty()
之后,然后放在 switchIfEmpty
之前的主要思想。
更新 2
模拟 class 复制和 运行 场景。 JsonObject
来自 gson 库。
public class MockExample {
@Test
public void testGenerateValue() {
Handler handler = new Handler();
handler.generateValue(new Request("testVal"))
.subscribe();
}
class Handler {
MockValueService valueService = new MockValueService();
MockRepositoryService repositoryService = new MockRepositoryService();
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.switchIfEmpty(Maybe.fromAction(() -> new Result(new JsonObject()))) //empty result
.toSingle()
.flatMap(value -> repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()));
}
}
class MockValueService {
public Maybe<Value> create(String arg) {
return Maybe.empty();
}
}
class MockRepositoryService {
public Single<Value> persist(Value value) {
return Single.just(value);
}
}
class Result {
private JsonElement json;
public Result(JsonElement json) {
this.json = json;
}
public JsonElement getJson() {
return json;
}
}
class Request {
private String arg;
public Request(String arg) {
this.arg = arg;
}
public String getArg() {
return arg;
}
}
class Value {
private JsonObject original;
public Value(JsonObject original) {
this.original = original;
}
public JsonObject toJson() {
return original;
}
}
}
通过模拟示例,我现在可以看到问题:
.switchIfEmpty(Maybe.fromAction(() -> ...))
为空,因为 Maybe.fromAction
永远不会产生成功值。你误以为是 fromCallable
.
persist
returns Single
需要将 flatMapSingle
合并到序列中。
- 为确保类型保持正确,您必须在
switchIfEmpty
调用之前移动映射。
试试这个设置:
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.flatMapSingleElement(value -> repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()))
.switchIfEmpty(Maybe.fromCallable(() -> new Result(new JsonObject())))
.toSingle()
;
}
我有以下通过 REST 响应式调用的方法:
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.switchIfEmpty(Maybe.fromAction(() -> new Result(new JsonObject()))) //empty result
.toSingle()
.flatMap(value -> repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()));
}
我可以用 Maybe.error(new Exception())
终止流,但调用方将收到我不想发送的错误响应。
当外部服务returns Maybe.empty()
时,是否可以return Single<Result>
(在中间终止流)而不恢复主流(来自toSingle()
行)?
更新
我尝试按照@akarnokd 的建议将flatMap
+ map
块放在switchIfEmpty
之前。首先,我将它们提取到单独的方法中:
private Single<Result> persistValue(Value value) {
return repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()));
}
并在主管道中使用此方法:
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.map(this::persistValue)
.switchIfEmpty(Maybe.fromAction(() -> new Result(new JsonObject()))) //empty result
.toSingle()
.cast(Result.class);
}
这一次,当 Maybe.empty()
被 return 编辑时,我得到:
Operation could not be performed as entity stream did not return any results: The MaybeSource is empty
java.util.NoSuchElementException: The MaybeSource is empty
因为它的空状态被传递给了persistValue
方法。也许我没明白把 map
放在 Maybe.empty()
之后,然后放在 switchIfEmpty
之前的主要思想。
更新 2
模拟 class 复制和 运行 场景。 JsonObject
来自 gson 库。
public class MockExample {
@Test
public void testGenerateValue() {
Handler handler = new Handler();
handler.generateValue(new Request("testVal"))
.subscribe();
}
class Handler {
MockValueService valueService = new MockValueService();
MockRepositoryService repositoryService = new MockRepositoryService();
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.switchIfEmpty(Maybe.fromAction(() -> new Result(new JsonObject()))) //empty result
.toSingle()
.flatMap(value -> repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()));
}
}
class MockValueService {
public Maybe<Value> create(String arg) {
return Maybe.empty();
}
}
class MockRepositoryService {
public Single<Value> persist(Value value) {
return Single.just(value);
}
}
class Result {
private JsonElement json;
public Result(JsonElement json) {
this.json = json;
}
public JsonElement getJson() {
return json;
}
}
class Request {
private String arg;
public Request(String arg) {
this.arg = arg;
}
public String getArg() {
return arg;
}
}
class Value {
private JsonObject original;
public Value(JsonObject original) {
this.original = original;
}
public JsonObject toJson() {
return original;
}
}
}
通过模拟示例,我现在可以看到问题:
.switchIfEmpty(Maybe.fromAction(() -> ...))
为空,因为Maybe.fromAction
永远不会产生成功值。你误以为是fromCallable
.persist
returnsSingle
需要将flatMapSingle
合并到序列中。- 为确保类型保持正确,您必须在
switchIfEmpty
调用之前移动映射。
试试这个设置:
public Single<Result> generateValue(Request request) {
return valueService.create(request.getArg())
.flatMapSingleElement(value -> repositoryService.persist(value))
.map(obj -> new Result(obj.toJson()))
.switchIfEmpty(Maybe.fromCallable(() -> new Result(new JsonObject())))
.toSingle()
;
}