鉴于这两个期货,我只有在条件成立时才需要运行第一个期货(参见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)
}
答案 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)