scala - future - map 与平面图

标签 scala future

我已经阅读了有关mapflatMap的文档,并且我了解flatMap用于接受Future参数并返回另一个Future的操作。我不完全理解的是为什么我要这样做。举个例子:

  • 用户点击了我的网络服务,要求“做某事”
  • 我下载了一个文件(很慢)
  • 我处理文件(占用大量CPU)
  • 渲染结果

  • 我了解我希望以后使用它来下载文件,但是我有两个选择来对其进行重新处理:
    val downloadFuture = Future {/* downloadFile */}
    val processFuture = downloadFuture map {/* processFile */}
    processFuture onSuccess { case r => renderResult(r) }
    

    要么
    val downloadFuture = Future {/* download the file */}
    val processFuture = downloadFuture flatMap { Future {/* processFile */} }
    processFuture onSuccess { case r => renderResult(r) }
    

    通过添加调试语句(Thread.currentThread().getId),我发现在两种情况下,processrender都在同一线程中发生(使用ExecutionContext.Implicits.global)。

    我是否会简单地使用flatMap解耦downloadFileprocessFile,并确保processFile始终在Future中运行,即使它不是从downloadFile映射的也是如此?

    最佳答案

    ensure that processFile always runs in a Future even if it was not mapped from downloadFile?



    对,那是正确的。

    但是,大多数情况下,您不会直接使用Future { ... },而是会使用返回Future的函数(来自其他库或您自己的函数)。

    想象以下功能:
    def getFileNameFromDB{id: Int) : Future[String] = ???
    def downloadFile(fileName: String) : Future[java.io.File] = ???
    def processFile(file: java.io.File) : Future[ProcessResult] = ???
    

    您可以使用flatMap组合它们:
    val futResult: Future[ProcessResult] =
      getFileNameFromDB(1).flatMap( name =>
        downloadFile(name).flatMap( file =>
           processFile(file)
        )
      )
    

    或使用来理解:
    val futResult: Future[ProcessResult] =
      for {
        name <- getFileNameFromDB(1)
        file <- downloadFile(name)
        result <- processFile(file)
      } yield result
    

    大多数情况下,您不会调用onSuccess(或onComplete)。通过使用这些函数之一,您可以注册一个回调函数,该函数将在Future完成时执行。

    如果在我们的示例中,您想呈现文件处理的结果,则将返回类似Future[Result]的内容,而不是调用futResult.onSuccess(renderResult)。在最后一种情况下,您的返回类型将为Unit,因此您无法真正返回任何内容。

    在Play Framework中,它可能类似于:
    def giveMeAFile(id: Int) = Action.async {
      for {
        name <- getFileNameFromDB(1)
        file <- downloadFile(name)
        processed <- processFile(file)
      } yield Ok(processed.byteArray).as(processed.mimeType))
    }
    

    关于scala - future - map 与平面图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31641190/

    相关文章:

    scala - Spark Dataframe - 窗口函数 - 插入和更新输出的滞后和超前

    list - 如何扩展 Scala 列表以启用不是按显式位置而是按给定谓词/条件的切片

    arrays - 以循环方式移动序列的最佳实践

    postgresql - DB 的 Scala future

    c++ - 并行运行时采用迭代器对的函数不起作用

    c++ - C++在主线程中等待 future 而无需while(true)

    scala - 尝试用两列 [Seq(), String] 创建数据框 - Spark

    scala - 相当于 javascript 运算符 ||在斯卡拉

    multithreading - Scala Future[T] 是否在内部阻塞? Scala Future 内部会发生什么?

    dart - Future.then返回意外的空值