【问题标题】:Handle Future with transform用变换处理未来
【发布时间】:2020-07-09 21:14:00
【问题描述】:

我在 Scala 上有一个电报机器人,如果它存在,我想将图像发送给用户,如果不存在,我想发送消息“对不起,图像不存在”。我有一个函数getImage(tag),它返回Future.successful(link)Future.failed(NoImageException(msg))

onCommand("/img") { implicit msg =>
  val tag = msg.text.get.drop("/img ".length)
  try {
    if (tag.isEmpty) throw new IndexOutOfBoundsException()
    service.getImage(tag).transform {
      case Success(link) => Success(
        try {
          replyWithPhoto(InputFile(link))
        } catch {
          case _ => reply(link) // maybe it isn't a photo...
        })
      case Failure(e) => Success(reply(e.getMessage))
    }.void
  } catch {
    case _: IndexOutOfBoundsException => reply("Empty argument list. Usage: /img tag").void
  }}

如果成功则此代码发送图像,但如果失败则不发送消息(但在这种情况下它肯定选​​择case Failure(e)

【问题讨论】:

  • 我认为你需要使用 onComplete 而不是 transform
  • @VladislavKievski 但在这种情况下它会返回 Unit 而不是 Future[Unit] 我不知道如何用惯用方式重写它:(
  • @RonaldSMerritt reply 函数返回什么?

标签: scala exception bots future


【解决方案1】:

reply 系列函数返回 Future[Message]。目前您将reply 的结果包装在Success 中,因此您的transform 的结果是Future[Future[Message]],这是行不通的。相反,您可以使用 transformWith,它期望其参数的结果为 Future

onCommand("/img") { implicit msg =>
  val tag = msg.text.get.drop("/img ".length)
  val message: Future[Message] =
    if (tag.isEmpty) reply("Empty argument list. Usage: /img tag")
    else {
      service.getImage(tag).transformWith {
        case Success(link) => replyWithPhoto(InputFile(link)).recoverWith {
          case _ => reply(link) // maybe it isn't a photo...
        }
        case Failure(e) => reply(e.getMessage)
      }
    }
  message.void
}

请注意,我还删除了两个 try 运算符。外部是不必要的,因为你可以使用if/else。内部根本不起作用,因为replyWithPhoto 返回一个Future。所以它不会抛出错误,当它失败时你需要recovertransform

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 2015-09-19
    • 2021-04-23
    • 2015-11-24
    • 1970-01-01
    相关资源
    最近更新 更多