当我需要库函数的上下文和单声道响应时,如何重构嵌套平面图?



我有一个反应式Web应用程序(Spring WebFlux(,我通过Azure存储中的POST API存储用户配置文件图像。如果存储桶不存在,我需要为用户创建一个存储桶。

服务层方法如下所示: (其中包含嵌套的 flatMaps - 这在反应式应用程序中被认为是一种不好的做法,并且是一种代码异味。我想重构这样没有嵌套的flatMap。有什么办法可以做到这一点吗?

public Mono<BlockBlobItem> processAndUpload(FilePart filePart) {
return Mono.subscriberContext().flatMap(context -> {
String userId = context.get(USER_ID_CONTEXT);
BlobContainerAsyncClient blobContainerClient = blobServiceAsyncClient.getBlobContainerAsyncClient(userId);
return blobContainerClient.exists()
.doOnEach(logOnNext(doesContainerExist -> {
if (doesContainerExist) {
LOGGER.info(STORAGE_CONTAINER_EXISTS_MSG);
} else {
LOGGER.info(STORAGE_CONTAINER_DOES_NOT_EXIST_MSG);
}
}))
.doOnEach(logOnError(err -> LOGGER.error(CONTAINER_CHECK_FAILURE_MSG, err.getMessage(), err)))
.flatMap(doesContainerExist -> {
if (doesContainerExist) {
return uploadFile(filePart, blobContainerClient, userId);
} else {
return blobContainerClient.createWithResponse(null, null)
.doOnEach(logOnComplete(response -> LOGGER.info(CONTAINER_CREATION_SUCCESS_MSG)))
.doOnEach(logOnError(err -> LOGGER.error(CONTAINER_CREATION_FAILURE_MSG, err.getMessage(), err)))
.then(uploadFile(filePart, blobContainerClient, userId));
}
});
});
}

恐怕只要您需要这两种上下文,嵌套flatMap是唯一的方法。

如果您谈论重构,我会将 lambda 表达式(或至少它们的右侧(移出该方法以实现可读性。还可以考虑先使用map来获取userId,只要您不需要初始context

public Mono<BlockBlobItem> processAndUpload(FilePart filePart) {
return Mono.subscriberContext()
.map(context -> context.get(USER_ID_CONTEXT))
.flatMap(userId -> {
var client = blobServiceAsyncClient.getBlobContainerAsyncClient(userId);
return client.exists()
.doOnEach(logOnNext(doesContainerExistLambda))
.doOnEach(logOnError(errLambda))
.flatMap(doesExist -> existenceHandler(filePart, client, userId));
}
);
}

名为doesContainerExistLambdaerrLambdaexistenceHandler的方法和 lambda 表达式是根据您的需要和注意事项进行更改的主题。代码片段的重点是突出显示可以移动到其他地方的内容。

相关内容

  • 没有找到相关文章

最新更新