Mono.then() 与 .and() 并行化

问题描述 投票:0回答:1

我之前将实体保存到表中,如下所示:

insertTableOne(foo).then(insertTableTwo(foo)).then(Mono.just(foo));

团队成员建议使用

.and()
来并行插入:
insertTableOne(foo).and(insertTableTwo(foo).thenRetuen(foo);

虽然我同意它看起来更干净,但我找不到任何使用

.and()
将同时执行两个插入的文档。我认为它仍然是连续的,除非明确声明与
Schedulers.parallel()
平行。

我错了吗?

spring-webflux project-reactor
1个回答
0
投票

两个例子的差异如下。

首先你必须记住,这里执行的一切都已完成

async
。意味着没有任何东西被阻挡。某些东西被触发,然后线程继续执行其他操作,直到返回某种形式的响应。

then 关键字在文档中的描述如下

让这个单声道完成,然后播放另一个单声道。

意味着它将启动

insertTableOne
然后完成后
insertTableTwo

所以是的,它们将按顺序执行。

如果我们在文档中查找

and
关键字:

将来自该单声道和另一个源的终止信号加入到返回的空单声道中

那么这意味着什么,这意味着当

Mono's
都终止时,无论出于何种原因,我们都将返回 void。如果先成功而后失败,或者相反,或者两者都失败,我们不在乎,双方都必须完成他们正在做的事情,然后我们将返回并继续。

是的,这意味着两人将同时被解雇

async
看看我在这里如何选择我的用词。不是
parallel
我正在写
async

这样想,如果我们是并行的,那就是 2 个人发送两封电子邮件。如果我们是异步的,则 1 个人发送 2 封邮件,但速度很快。这也意味着,2 个单独的人将分别处理一封电子邮件,或者在异步情况下,一个人处理 2 封电子邮件,但速度很快。

因此,在您的情况下,它可能是来自单个调度程序的同一线程为事件循环调度两个作业,或者是两个单独的线程调度工作。这应该不重要,你也不应该关心,因为这取决于图书馆来处理。

你应该关心的是你想如何处理失败的错误,

and()
无论结果如何都会继续,所以你不知道某件事是否失败。

并强调你最后的陈述:

我认为除非明确说明是并行的,否则它仍然是顺序的

webflux 中的所有内容默认都是

async
,如果您明确声明的话也可以是
parallel
。您可以按
顺序
执行事情async

一个例子:

// This will execute n + 1 in sequence taking one item at the time preserving order and print 2,3,4
Flux.just(1,2,3).map(n -> n + 1).subscribe(n -> System.out.println(n));

// This will iterate through and execute n + 1 all at once, and order back is not guaranteed as the subscribe will print in order of what completed first, might be 2,3,4 might be 3,4,2 or 2,4,3
Flux.just(1,2,3).map(n -> n + 1).subscribe(n -> System.out.println(n));

上面的例子是理论上的,但我想强调的是,

async
不是
paralellel
,但异步可以是
sequential

© www.soinside.com 2019 - 2024. All rights reserved.