在maybe为空时终止流而不引发异常

ffvjumwh  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(358)

我有以下方法,通过rest进行React性调用:

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()) 但是主叫方会得到我不想发送的错误响应。
有可能回来吗 Single<Result> (在中间终止流)当外部服务返回时 Maybe.empty() ,而不恢复主流(从 toSingle() 行)?
更新
我试着把 flatMap + map 之前阻止 switchIfEmpty 就像@akarnokd建议的那样。首先,我将它们提取到单独的方法中:

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() 我得到:
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
模仿类来复制和运行场景。 JsonObject 来自gson lib。

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;
        }
    }
}
evrscar2

evrscar21#

通过模拟示例,我现在可以看到以下问题: .switchIfEmpty(Maybe.fromAction(() -> ...)) 是空的,因为 Maybe.fromAction 从不产生成功的价值。你错把它当成 fromCallable . persist 退货 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()
            ;
}

相关问题