【问题标题】:Handling Scala Futures处理 Scala 期货
【发布时间】:2014-06-21 00:43:47
【问题描述】:

我正在编写 Scala 代码,用于检查 Amazon S3 上的某个位置是否有可用的 zip 文件。如果是,我想返回路径;如果不是,我想创建它并然后返回路径。答案都是一样的(假设没有例外)。

我将Rhinofly play-s3 库用于我的S3 抽象,但我认为这不太相关。该库确实使用了 Scala Future,这就是这里的重点。我的问题是 Scala 不喜欢在开始时不可用时创建 zip 的方法的返回类型。

这是我的代码:

def zip(key: String): Future[String] = {
    val zipFileName = key + ".zip"
    val zipFile = bucket get zipFileName //Returns a Future[BucketFile] or S3Exception
    zipFile.map(bucketFile => bucketFile.name).recover {
      case S3Exception(status, code, message, originalXml) => createZip(key)
      case _ => "Who cares for now?"
    }
}

让我们假设一条快乐的道路,唯一可能发生的例外是没有现有 zip 的 404。

同时,createZip(key) 返回一个Future[String]

我得到的编译错误是这样的:

type mismatch;
 found   : scala.concurrent.Future[String]
 required: String

所以我希望zip 方法返回Future[String]。我认为从zipFilebucketFile.namemap 返回Future[String],而createZip 肯定返回Future[String]

那么问题是什么?为什么String 是必需的返回类型?如何重写其中一个或两个方法来实现我的目标?

【问题讨论】:

    标签: scala amazon-s3 future


    【解决方案1】:

    recover 会将Future 恢复为默认值。在这种情况下,String。你想要的是recoverWith另一个 Future 恢复Future

    def zip(key: String): Future[String] = {
        val zipFileName = key + ".zip"
        val zipFile = bucket get zipFileName //Returns a Future[BucketFile] or S3Exception
        zipFile.map(bucketFile => bucketFile.name).recoverWith {
          case S3Exception(status, code, message, originalXml) => createZip(key)
        }
    }
    

    【讨论】:

      【解决方案2】:

      您有一个异步恢复(即,您的恢复返回 Future[String] 而不是 String。使用 recoverWith,它允许您使用创建 Future 的回调。请注意“谁在乎呢? " 需要通过调用 Future.success("Who cares for now") 将其提升为 Future,或者您可以让错误消失。

      【讨论】:

        猜你喜欢
        • 2017-09-30
        • 1970-01-01
        • 2016-01-24
        • 1970-01-01
        • 1970-01-01
        • 2017-03-26
        • 1970-01-01
        • 2014-01-10
        • 1970-01-01
        相关资源
        最近更新 更多