【发布时间】:2018-01-19 18:59:40
【问题描述】:
我有以下伪代码。
依次调用fetch、fetchRecordDetail、upload和notifyUploaded函数。每个函数都返回一个未来事件,但第一个函数返回 Option[T],然后(fetchRecordDetail、upload 和notifyUploaded)调用我只需要携带 Some[T] 类型并忽略 None。
不幸的是,我通过太多的Await.ready 调用实现了以下输出。
预期输出
通知列表(UploadResult(a_detail_uploaded), UploadResult(c_detail_uploaded))
代码
def fetch(id: String): Future[Option[Record]] = Future {
Thread sleep 100
if (id != "b" && id != "d") {
Some(Record(id))
} else None
}
def fetchRecordDetail(record: Record): Future[RecordDetail] = Future {
Thread sleep 100
RecordDetail(record.id + "_detail")
}
def upload(recordDetail: RecordDetail): Future[UploadResult] = Future {
Thread sleep 100
UploadResult(recordDetail.id + "_uploaded")
}
def notifyUploaded(results: Seq[UploadResult]): Future[Unit] = Future{ println("notified " + results)}
val result: Future[Unit] = //Final call to 'notifyUploaded' goes here
Await.ready(result, Duration.Inf)
有人可以通过避免Await.ready 调用来帮助即兴创作此代码吗?
val ids: Seq[String] = Seq("a", "b", "c", "d")
def filterSome(s:String) = fetch(s) map ((s, _)) collect { case (s, Some(v)) => v }
val validData = ids map filterSome
Await.ready(Future.sequence(validData), Duration.Inf)
val records = validData.map(_.value.get.toOption)
val recordDetails = records.flatten map fetchRecordDetail
Await.ready(Future.sequence(recordDetails), Duration.Inf)
val uploadResult = recordDetails.map(_.value.get.toOption).flatten map upload
Await.ready(Future.sequence(uploadResult), Duration.Inf)
val seqUploadResult = uploadResult.map(_.value.get.toOption)
val result: Future[Unit] = notifyUploaded(seqUploadResult.flatten)
Await.ready(result, Duration.Inf)
【问题讨论】:
-
编写而不是等待