如何简洁的写出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 被隔离,其他方法可以进行单元测试。如果你需要阻止执行,只在最后执行,如果你需要命令执行它们,请使用 mapflatMap 链接 Futures。还要小心Duration.Inf,如果你真的需要阻塞,那么你会想要一些定义的超时。