如何简洁的写出Awaited的异步代码?
How to write an asynchronous code that Awaited concisely?
我是 Scala 的初学者。
如果下面的代码中有更简洁的部分,请告诉我。
作为补充,我想同步调用每个 Future 方法。
◆获取用户方法:
def getUser: Option[User] = {
Await.ready(
twitterService.getUser(configService.getString(TWITTER_USERNAME_CONF)),
Duration.Inf)
.value
.flatMap(x => Option(x.getOrElse(null)))
}
◆ 处理方法:
def process : Unit =
for {
user <- getUser
} yield {
Await.ready(
twitterService.delete(user.id, configService.getString(TWITTER_SEARCH_KEYWORD)),
Duration.Inf)
.value
.foreach {
case Success(tweets) => tweets.foreach(tweet => println(s"Delete Successfully!!. $tweet"))
case Failure(exception) => println(s"Failed Delete.... Exception:[$exception]")
}
}
我对用户和推文数据类型做了一些假设,但我会将其重写为:
def maybeDeleteUser(userName: String, maybeUser: Option[User]): Future[String] =
maybeUser match {
case Some(user) =>
twitterService.delete(user.id, configService.getString(TWITTER_SEARCH_KEYWORD)).map {
case Failure(exception) => s"Failed Delete.... Exception:[${exception.getMessage}]"
case Success(tweets) => tweets.map(tweet => s"Delete Successfully!!. $tweet").mkString(System.lineSeparator())
}
case _ => Future.successful(s"Failed to find user $userName")
}
def getStatusLogMessage: Future[String] = {
val userName = configService.getString(TWITTER_USERNAME_CONF)
for {
maybeUser <- twitterService.getUser(configService.getString(TWITTER_USERNAME_CONF))
statusLogMessage <- maybeDeleteUser(userName, maybeUser)
} yield statusLogMessage
}
def process: Unit = {
val message = Await.result(getStatusLogMessage, Duration.Inf)
println(message)
}
这样你的副作用,即 println
被隔离,其他方法可以进行单元测试。如果你需要阻止执行,只在最后执行,如果你需要命令执行它们,请使用 map
和 flatMap
链接 Future
s。还要小心Duration.Inf
,如果你真的需要阻塞,那么你会想要一些定义的超时。
我是 Scala 的初学者。 如果下面的代码中有更简洁的部分,请告诉我。 作为补充,我想同步调用每个 Future 方法。
◆获取用户方法:
def getUser: Option[User] = {
Await.ready(
twitterService.getUser(configService.getString(TWITTER_USERNAME_CONF)),
Duration.Inf)
.value
.flatMap(x => Option(x.getOrElse(null)))
}
◆ 处理方法:
def process : Unit =
for {
user <- getUser
} yield {
Await.ready(
twitterService.delete(user.id, configService.getString(TWITTER_SEARCH_KEYWORD)),
Duration.Inf)
.value
.foreach {
case Success(tweets) => tweets.foreach(tweet => println(s"Delete Successfully!!. $tweet"))
case Failure(exception) => println(s"Failed Delete.... Exception:[$exception]")
}
}
我对用户和推文数据类型做了一些假设,但我会将其重写为:
def maybeDeleteUser(userName: String, maybeUser: Option[User]): Future[String] =
maybeUser match {
case Some(user) =>
twitterService.delete(user.id, configService.getString(TWITTER_SEARCH_KEYWORD)).map {
case Failure(exception) => s"Failed Delete.... Exception:[${exception.getMessage}]"
case Success(tweets) => tweets.map(tweet => s"Delete Successfully!!. $tweet").mkString(System.lineSeparator())
}
case _ => Future.successful(s"Failed to find user $userName")
}
def getStatusLogMessage: Future[String] = {
val userName = configService.getString(TWITTER_USERNAME_CONF)
for {
maybeUser <- twitterService.getUser(configService.getString(TWITTER_USERNAME_CONF))
statusLogMessage <- maybeDeleteUser(userName, maybeUser)
} yield statusLogMessage
}
def process: Unit = {
val message = Await.result(getStatusLogMessage, Duration.Inf)
println(message)
}
这样你的副作用,即 println
被隔离,其他方法可以进行单元测试。如果你需要阻止执行,只在最后执行,如果你需要命令执行它们,请使用 map
和 flatMap
链接 Future
s。还要小心Duration.Inf
,如果你真的需要阻塞,那么你会想要一些定义的超时。