当前位置: 首页 > 知识库问答 >
问题:

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

颜楚青
2023-03-14

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

服务层方法如下所示:(它包含嵌套的平面地图--这在反应性应用程序中被认为是一种不好的做法,而且是一种代码气味。)我想重构,这样就没有嵌套的平面地图。有什么办法可以做到这一点吗?

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));
            }
          });
    });
  }

共有1个答案

许彭祖
2023-03-14

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

如果您谈到重构,我会将lambda表达式(或者至少是它们的右侧)移出方法,以实现可读性。另外,只要不需要初始的上下文,请考虑首先使用map来获取userid

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表达式是根据需要和考虑进行更改的主题。代码段的重点是要强调可以转移到其他地方的内容。

 类似资料:
  • 在Javascript中调用顶级函数时,函数中的this关键字引用默认对象(如果在浏览器中,则为窗口)。我的理解是,这是作为方法调用函数的一种特殊情况,因为默认情况下,它是在窗口上调用的(如John Resig的书《JavaScript忍者的秘密》第49页所述)。实际上,下面代码中的两个调用是相同的。 到目前为止还不错...这是我不明白的部分: 当一个函数嵌套在另一个函数中并在未指定要调用的对象的

  • 我有这段代码。第一个非嵌套的映射输出了一些东西,而嵌套的映射没有。我想我理解为什么第二个不起作用。这是一个延迟序列,Perl 6正在收集结果。那很好。但是,第一个(非嵌套的)映射不是以同样的方式懒惰吗?如果我不对映射结果做任何操作,它将如何输出任何内容?也就是说,第一个怎么懒惰?is是否会自动获取一个接收器上下文,在该上下文中,我必须显式地向嵌套的接收器提供接收器(或其他内容)?不知何故,我认为P

  • 我需要生成平均响应时间和平均延迟时间。csv文件。 我在一个Web应用程序中有50个API,我需要为多达50个并发用户对其进行测试。 我尝试过聚合图及其插件,但它只生成平均经过的时间。例如,我得到了聚合已用时间:在此处输入图像描述 我的客户要求我用他们的图表为平均响应时间和平均延迟时间生成类似的电子表格报告。 如果JMeter中有什么方法可以完成,有人可以帮我吗? 在此输入图像描述目前,我已经使用

  • 我想通过flatMap向数据集生成的每个组应用一个函数。groupBy(分组依据)。尝试调用flatMap时,我发现编译器错误: 我的代码: 事实上,在flink-0.9-SNAPSHOT的留档中没有列出或类似的。是否有类似的方法可以使用?如何在节点上单独实现每个组的所需分布式映射?

  • RDD转换和操作只能由驱动程序调用,不能在其他转换内部调用;例如,rdd1。地图(x)= 正如错误所说,我试图在主映射函数中映射(转换)一个JavaRDD对象,ApacheSpark怎么可能呢? 主要JavaPairRDD对象(TextFile和Word是定义的类): 和地图功能: 我还尝试了foreach映射函数,但不起作用。(当然还有SPARK-5063)

  • 我有一个这样的结构: 和看起来像这样 这不是最好的设计-我知道,但我没有能力改变这个设计。 我正在尝试找到一种方法,将此结构扁平化为单个,并找到一个itemTag 但这仅搜索项目列表的一个级别。如果我想更深入,我可以简单地做: 这很好。但我正试图找到一种更具可扩展性的方法来实现这一点,它可以像嵌套列表一样深入。有没有有效的方法来做到这一点?