首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mono.defer()的真实用例是什么?

Mono.defer()的真实用例是什么?
EN

Stack Overflow用户
提问于 2021-07-14 21:33:54
回答 3查看 127关注 0票数 0

我知道Mono.defer()是做什么的,但是我应该什么时候使用它呢?我知道其中一个用例是推迟返回Mono的函数中的一些阻塞副作用,但这通常是一个糟糕的做法(将副作用放在返回MonoFlux的函数中)。当我想在Mono中包装一些阻塞代码时,可以使用Mono.fromCallable()。那么使用Mono.defer()的最佳案例是什么呢?

EN

回答 3

Stack Overflow用户

发布于 2021-07-14 23:28:08

Mono.fromCallable()用于常规延迟服务调用。Mono.defer()会生成一个Mono,只有当您订阅时它才会这样做。因此,您可能决定不在合成阶段创建此Mono,而是完全在目标订阅者上创建。

票数 0
EN

Stack Overflow用户

发布于 2021-11-14 23:16:07

@a.khakh

帮助我的一个非常简单的用例是在另一个线程中执行阻塞代码,即处理那个阻塞调用,这样主线程就不会阻塞我。

我发现需要在另一个线程中使用defer进行订阅,在本例中是在project reactor提供的、由Simon Basle编程的Scheduler中。

如果你使用defer + subscribeOnSchedulers.boundedElastic的组合,你将使你的代码是非阻塞的,或者更确切地说,它不会阻塞你的应用程序,从而消除主线程的争用。

下图显示了Combo的第三个组件在内部使用了defer和Scheduler,这样就不会阻塞应用程序。

  • 忽略名为ui.access()的方法,它是vaadin框架的一部分。

代码语言:javascript
运行
复制
Mono.defer(()  -> this.reactiveRandomNumbers.monoFrecuency(event.getValue().getSize())) <1>
                        .doOnEach(signal -> log.info("Thread name doOnNext(): {}", Thread.currentThread().getName()))
                        .subscribeOn(Schedulers.boundedElastic())
                        .subscribe(subscribeMap -> {
                            ui.access(() -> {
                                log.info("Thread name subscribe(): {}", Thread.currentThread().getName());
                                this.execute(event.getValue().getSize(), e -> subscribeMap);
                            });
                        });
票数 0
EN

Stack Overflow用户

发布于 2021-11-23 20:25:26

有时你需要懒惰地计算一些同步的东西。

例如,我们有一个异步服务

代码语言:javascript
运行
复制
public interface SomeService {

    Mono<User> getUserByName(String name);

    Mono<CreateUserResult> createUser(User user);

}

以及一个端点,它在此服务中查找用户,如果没有找到,则创建该端点。但在创建之前,必须在特殊的线程池中同步执行一些繁重的计算。所以

代码语言:javascript
运行
复制
someService.getUserByName(name)
                .switchIfEmpty(Mono.defer(() -> {
                    var someHeavyCalculatedData = localHeavyService.doSomethingNecessary(name);
                    return someService.createUser(new User(name, someHeavyCalculatedData));
                }).subscribeOn(specialScheduler));

当然,您可以说我们可以使用Mono.fromCallable,并像这样做

代码语言:javascript
运行
复制
someService.getUserByName(name)
                .switchIfEmpty(Mono.fromCallable(() -> localHeavyService.doSomethingNecessary(name))
                        .subscribeOn(specialScheduler)
                        .flatMap(someHeavyCalculatedData -> someService.createUser(new User(name, someHeavyCalculatedData)))
                );

但是,反应链中的每个方法调用都会导致在内存中创建大量对象。好吧,对于一个单独的调用,你可能不会注意到任何东西,但随着更高的负载频繁地分配内存,然后由GC释放它会导致你的应用程序变慢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68379116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档