简体   繁体   English

使用 Optional 的 ifPresentOrElse 方法但返回 promise 而不是 void

[英]Using Optional's ifPresentOrElse method but return promise instead of void

I'm trying to get my around a current issue I'm facing.我正在努力解决我面临的当前问题。

I have a function that returns an Optional type (an object with a few properties)我有一个返回 Optional 类型的 function(具有一些属性的 object)

One of the properties is an url that might be present or not.其中一个属性是 url,它可能存在也可能不存在。 I extract that url in order to make an HTTP request我提取 url 以发出 HTTP 请求

injectedClass.method(tenant.clientKey()).flatMap(optionalProperty ->
                        optionalProperty.ifPresentOrElse(fi -> {
                                Blocking.get(() -> httpClientProvider.withHttpClient((HttpClient httpClient) ->
                                    httpClient.request(URI.create(optionalProperty.webTriggerUrl()), (RequestSpec spec) -> {
                                        LogstashMarker markers = append("webTriggerUrl", fi.webTriggerUrl()).and(append("method", "Post").and(append("behaviour", objectMapper.writeValueAsString(baseDTO))));
                                        logger.debug(markers, "Executed a Post request to something webTriggerUrl");
                                        spec.method(HttpMethod.POST);
                                        spec.getBody().type(HttpHeaderValues.APPLICATION_JSON).text(objectMapper.writeValueAsString(baseDTO), CharsetUtil.UTF_8);

                                        final MutableHeaders headers = spec.getHeaders();
                                        headers
                                                .set(HttpHeaderNames.USER_AGENT, userAgent);

                                        headers.set(CorrelationId.HEADER_NAME, correlationId.id());

                                    })
                            )).then(resp -> logger.info("ok"));
                        }, () -> logger.error("something"))

Blocking.get brings back a Promise and I get an error in my code basically saying that the expected return type of ifPresentOrElse should be void and not Promise Blocking.get 带回一个 Promise 并且我在我的代码中得到一个错误,基本上说ifPresentOrElse的预期返回类型应该是 void 而不是 Promise

Is there a functional and better way to achieve this?有没有一种功能更好的方法来实现这一目标?

Yes there are ways, but you also have to decide what to do if the Optional is empty.是的,有很多方法,但是如果Optional为空,您还必须决定要做什么。 Currently you want to return a Promise if the optional is present, and return nothing ("void") if it is empty.当前,如果存在可选项,您希望返回Promise ,如果为空,则不返回任何内容(“void”)。 This doesn't work, the types for both branches need to be the same.这是行不通的,两个分支的类型必须相同。

You can just use optionalProperty.map() to map your original Optional to a Optional<Promise> , and then use ifPresentOrElse , to do something with either the Promise or with the empty Optional, eg logging as you seem to be doing in your case.你可以只使用optionalProperty.map()到 map 你原来的OptionalOptional<Promise> ,然后使用ifPresentOrElse来对 Promise 或空的 Optional 做一些事情,例如你在你的情况下似乎正在做的日志记录.

But you also have a higher-level flatMap which I'm unclear from which type it is.但是您还有一个更高级别的flatMap ,我不清楚它是哪种类型。 Does this flatmap a Promise ?这个平面图是Promise吗? Then you must return a Promise also from the other branch of the optional, and you could use optionalProperty.map(...).orElse( <create empty Promise here> ) .然后,您还必须从可选的另一个分支返回 Promise,并且您可以使用optionalProperty.map(...).orElse( <create empty Promise here> )

Also check out orElseGet() instead of orElse() , if you want to create the empty branch lazily (via Supplier ).如果您想懒惰地创建空分支(通过Supplier ),还可以检查orElseGet()而不是orElse() ) 。

ifPresentOrElse returns void . ifPresentOrElse返回void What you probably want is a combination of map and orElseGet :您可能想要的是maporElseGet的组合:

optionalProperty.map(/* code to return a Promise */)
        .orElseGet(() -> /* code to return a Promise that is immediately resolved */);

Inside the supplier to orElseGet() you can put your logger.error statement.orElseGet()的供应商内部,您可以放置logger.error语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM