Java 在Flux/Mono中应该使用什么来连接耦合项

Java 在Flux/Mono中应该使用什么来连接耦合项,java,reactive-programming,project-reactor,Java,Reactive Programming,Project Reactor,在JS中,您可以使用 但对于Flux/Mono,我找不到这样的解决方案。当您处理不同的项目之后必须将它们组合在一起使用时,最佳做法是什么?这取决于您希望如何组合它们。 按顺序?使用Flux.concat 所有这些都是平行的?使用Flux.zip 如果您只希望得到一个结果,Mono.zipWith可能适合您。这取决于您希望如何组合它们。 按顺序?使用Flux.concat 所有这些都是平行的?使用Flux.zip 如果您只希望得到一个结果,Mono.zipWith可能适合您。有很多“合并运算符”

在JS中,您可以使用


但对于Flux/Mono,我找不到这样的解决方案。当您处理不同的项目之后必须将它们组合在一起使用时,最佳做法是什么?

这取决于您希望如何组合它们。 按顺序?使用
Flux.concat
所有这些都是平行的?使用
Flux.zip

如果您只希望得到一个结果,
Mono.zipWith
可能适合您。

这取决于您希望如何组合它们。 按顺序?使用
Flux.concat
所有这些都是平行的?使用
Flux.zip

如果您只希望得到一个结果,
Mono.zipWith
可能适合您。

有很多“合并运算符” zip、concat、merge和combinelateest是主要的三种

Zip允许您组合流,其中项目将在流中以1对1的关系分组。这就是您丢失最后一个元素的原因

当您不确定每个流的数量和提供事件的频率时,可以使用concat(将另一个流添加到第一个流的末尾)、merge(其中项目按照两个流的出现顺序放置在最终流上)或合并最新的(将每个流的最后两个事件变为其他事件).


你的案子听起来像是合并案

有很多“合并运算符” zip、concat、merge和combinelateest是主要的三种

Zip允许您组合流,其中项目将在流中以1对1的关系分组。这就是您丢失最后一个元素的原因

当您不确定每个流的数量和提供事件的频率时,可以使用concat(将另一个流添加到第一个流的末尾)、merge(其中项目按照两个流的出现顺序放置在最终流上)或合并最新的(将每个流的最后两个事件变为其他事件).


你的案子听起来像是合并案

经过一些更改后,我的代码如下所示

public Mono<Item> createItem(final @NonNull String userName, String description, String[] tags,
                             @NonNull Flux<ImageDTO> photos) {
    val item = initItem(userName);
    item.setDescription(description);
    if (null != tags) {
        item.getTags().addAll(Arrays.asList(tags));
    }

    return photos.flatMap(photo -> imageService.storeImage(photo.getStream(), photo.getExt()))
        .reduce(item, (item1, photoIri) -> {
            item1.getPhotos().add(photoIri);
            return item1;
        })
        .flatMap(itemRepository::save)
        .flatMap(createdItem -> {
            val itemHistory = getHistoryForCreatedItem(userName, createdItem);
            return itemHistoryRepository.save(itemHistory).then(Mono.just(createdItem));
        });
}
public Mono createItem(最终@NonNull字符串用户名、字符串描述、字符串[]标记、,
@非零通量照片){
val item=initItem(用户名);
项目说明(说明);
if(null!=标记){
item.getTags().addAll(Arrays.asList(tags));
}
返回photos.flatMap(photo->imageService.storeImage(photo.getStream(),photo.getExt())
.减少(项目,(项目1,photoIri)->{
item1.getPhotos().add(photoIri);
返回项目1;
})
.flatMap(itemRepository::save)
.flatMap(createdItem->{
val itemHistory=getHistoryForCreatedItem(用户名,createdItem);
返回itemHistoryRepository.save(itemHistory)。然后返回(Mono.just(createdItem));
});
}
目前我不喜欢:

  • .减少(项目,(项目1,photoIri)->
  • .then(Mono.just(createdItem))

经过一些更改后,我的代码如下所示

public Mono<Item> createItem(final @NonNull String userName, String description, String[] tags,
                             @NonNull Flux<ImageDTO> photos) {
    val item = initItem(userName);
    item.setDescription(description);
    if (null != tags) {
        item.getTags().addAll(Arrays.asList(tags));
    }

    return photos.flatMap(photo -> imageService.storeImage(photo.getStream(), photo.getExt()))
        .reduce(item, (item1, photoIri) -> {
            item1.getPhotos().add(photoIri);
            return item1;
        })
        .flatMap(itemRepository::save)
        .flatMap(createdItem -> {
            val itemHistory = getHistoryForCreatedItem(userName, createdItem);
            return itemHistoryRepository.save(itemHistory).then(Mono.just(createdItem));
        });
}
public Mono createItem(最终@NonNull字符串用户名、字符串描述、字符串[]标记、,
@非零通量照片){
val item=initItem(用户名);
项目说明(说明);
if(null!=标记){
item.getTags().addAll(Arrays.asList(tags));
}
返回photos.flatMap(photo->imageService.storeImage(photo.getStream(),photo.getExt())
.减少(项目,(项目1,photoIri)->{
item1.getPhotos().add(photoIri);
返回项目1;
})
.flatMap(itemRepository::save)
.flatMap(createdItem->{
val itemHistory=getHistoryForCreatedItem(用户名,createdItem);
返回itemHistoryRepository.save(itemHistory)。然后返回(Mono.just(createdItem));
});
}
目前我不喜欢:

  • .减少(项目,(项目1,photoIri)->
  • .then(Mono.just(createdItem))

如果我的流量有2个项目,另一个流量有3个项目,zip将返回2个元组,我在第二个流量中丢失了最后一个项目。如果我的流量有2个项目,另一个流量有3个项目,zip将返回2个元组,我在第二个流量中丢失了最后一个项目。我的典型流程是:创建类别->使用此类别->使用此项创建两个历史记录项->返回项这实际上听起来像这样:service.createItem().doOnNext({itemCreated->HistoryService.createItems.flatMap{})我知道在评论中写这是很粗糙的,但是如果你想创建历史,那么它应该起到作用,然后异步保存它作为副作用“…您不应该在doOn***操作符中执行繁重的I/O操作。这些操作是为日志记录或轻微的副作用操作而设计的。。。"这就是为什么我不太明白createItem#1->创建其他项目#2#3->返回#1的最佳方式是什么。你永远不应该在同一个线程上执行繁重的操作。如果你将这些操作委托给不同的调度程序,我看不出问题所在。如果我没记错,flatmap使用调度程序参数。你也可以返回strcreateItem#1中的eam在其上放置了一个装饰器,该装饰器将使用history creation+subscribe执行平面图,以便运行操作,并仅返回createItem#1我的典型流程是:创建类别->使用此类别创建项目->使用此项目创建两个历史项目->返回项目这听起来像这样:service.createItem().doOnNext({itemCreated->HistoryService.createItems.flatMap{})我知道这在注释中编写很粗糙,但是如果您希望创建历史记录,然后异步将其保存为副作用,那么它应该会起作用。关于doOnNext,我在我的另一个问题上得到了类似注释的提示“…您永远不应该在doOn***操作符中执行繁重的I/O操作。这些操作用于日志记录或轻微的副作用操作…”这就是为什么我不太理解的原因