Futures - map vs flatmap

前端 未结 4 1634
长发绾君心
长发绾君心 2020-12-23 09:59

I\'ve read the docs about map and flatMap and I understand that flatMap is used for an operation that accepts a Future pa

4条回答
  •  [愿得一人]
    2020-12-23 10:49

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

    Yes that is correct.

    However most of the time you wouldn't use Future { ... } directly, you would use functions (from other libraries or your own) which return a Future.

    Imagine the following functions :

    def getFileNameFromDB{id: Int) : Future[String] = ???
    def downloadFile(fileName: String) : Future[java.io.File] = ???
    def processFile(file: java.io.File) : Future[ProcessResult] = ???
    

    You could use flatMap to combine them :

    val futResult: Future[ProcessResult] =
      getFileNameFromDB(1).flatMap( name =>
        downloadFile(name).flatMap( file =>
           processFile(file)
        )
      )
    

    Or using a for comprehension :

    val futResult: Future[ProcessResult] =
      for {
        name <- getFileNameFromDB(1)
        file <- downloadFile(name)
        result <- processFile(file)
      } yield result
    

    Most of the time you would not call onSuccess (or onComplete). By using one of these functions you register a callback function which will be executed when the Future finishes.

    If in our example you would like to render the result of the file processing, you would return something like Future[Result] instead of calling futResult.onSuccess(renderResult). In the last case your return type would be Unit, so you can not really return something.

    In Play Framework this could look like :

    def giveMeAFile(id: Int) = Action.async {
      for {
        name <- getFileNameFromDB(1)
        file <- downloadFile(name)
        processed <- processFile(file)
      } yield Ok(processed.byteArray).as(processed.mimeType))
    }
    

提交回复
热议问题