Scala中的条件性未来

时间:2016-11-24 05:15:34

标签: scala

鉴于这两个期货,我只有在条件成立时才需要运行第一个期货(参见if y>2)。但是我得到了例外Future.filter predicate is not satisfied。这意味着什么以及如何修复示例?

object TestFutures extends App {

  val f1 = Future {
    1
  }

  val f2 = Future {
    2
  }

  val y = 1

  val x = for {
    x1 <- f1 if y>2
    x2 <- f2
  }  yield x1 + x2


  Thread.sleep(5000)
  println(x)
}

2 个答案:

答案 0 :(得分:3)

filter并不是你应该能够在Future上做的事情 - 那些没有通过条件的Future会返回什么?在您的示例中:我们仍然需要x1的值if(即使yield x1 + x2未通过)filter

因此,Future上的x1方法设计为在谓词计算结果为false时失败。这是各种各样的“断言”。您可能更喜欢这样的东西(如果条件失败,则为val x = for { x1 <- if (y > 2) f1 else Future.successful(/* some-default-value-for-x1 */) x2 <- f2 } yield x1 + x2 提供默认值):

    func databaseRequest(size: String, interior: String, fuel: String) {
    let baseURL = "https://$ACCOUNT-bluemix.cloudant.com/cars/_design/car_index/_search/car_index_name?q="
    let queryURL = "size:\(size)"
    let completeURL: String = baseURL + queryURL

    let completeURLModified = completeURL.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
    let requestURL = URL(string: completeURLModified!)

    var request = URLRequest(url: requestURL!)
    request.httpMethod = "GET"
    request.setValue("Basic \(credentials)", forHTTPHeaderField: "Authorization")

    let task = URLSession.shared.dataTask(with: request){data, response, error in

        guard error == nil else{
            print("There was an error:", error as Any)
            return
        }

        guard data == data else{
            print("Data is empty")
            return
        }

        let jsonResponse = try! JSONSerialization.jsonObject(with: data!, options: [])
        print("This is JSON Response", jsonResponse)

        }; task.resume()
    }

答案 1 :(得分:3)

该问题包含一些术语问题。

鉴于要求,“我只需要在条件为真时运行第一个(未来)”,那么该要求的一个可能实现将是:

val f1 = if (cond) Some(Future(op)) else None

这是因为Future一旦定义就会开始执行。

回到问题中的表达式:

val x = for {
  x1 <- f1 if y>2
  x2 <- f2
}  yield x1 + x2

这是说“我想要f1 if(cond) 结果 ”而不是“我想 执行 f1 if(cond)“。

这将是一种方式:(注意期货如何在for-comprehension中定义,条件在外面):

val x = if (y > 2) {
  for {
      x1 <- Future(op1)
      x2 <- Future(op2)
  }  yield x1 + x2
} else ???

在for-comprehension中正确使用警卫是为了对来自for-comprehension所表达的计算的值的表达式进行评估。例如:

“仅当f2的结果大于f1”时才会执行 y

val x = for {
  x1 <- f1
  x2 <- Future(op) if x1 > y
}  yield x1 + x2

注意这里的条件如何涉及计算的中间结果(在这种情况下为x1

旁注:等待未来的结果,请使用Await.result(fut, duration)代替Thread.sleep(duration)