【问题标题】:applying future where can be exception comes在可能出现异常的地方应用未来
【发布时间】:2014-09-26 20:31:35
【问题描述】:

这段代码运行良好,但我想通过Future 管理线程。 sendSMS 方法执行通常需要 3 到 5 秒,我想申请未来并申请在一个地方但想知道它是否足够?

val c = for {
            t <- Future { doSendSms("+9178787878787","i scare with threads") }
          } yield t
c.map { res =>
        res match {
          case e: Error => {
            Ok(write(Map("result" -> "error")))
          }
          case Success() => {
            Ok(write(Map("result" -> "success")))
          }

def doSendSms(recipient: String, body: String): SentSmsResult = {
    try {
      sendSMS(recipient, body)
      Success()
    } catch {
      case twilioEx: TwilioRestException =>
          return Error(twilioEx.toString)
      case e: Exception =>
          return Error(e.toString)
    }
  }


def sendSMS(smsTo: String, body: String) = {
    val params = Map("To" -> smsTo, "From" -> twilioNumber, "Body" -> body)
    val messageFactory = client.getAccount.getSmsFactory
    messageFactory.create(params)
  }// sending sms from twilio, this method takes 3 to 5 seconds to execute

如果不是如何在这段代码中管理 Future

【问题讨论】:

    标签: multithreading scala playframework thread-safety future


    【解决方案1】:

    我会使用recover:

    val c = for {
      t <- doSendSms("+9178787878787","i scare with threads")
    } yield t
    
    def doSendSms(recipient: String, body: String): Future[SentSmsResult] = 
      Future {
        sendSMS(recipient, body)
      }
      .recover {
        case twilioEx: TwilioRestException => Error(twilioEx.toString)
        case e: Exception => Error(e.toString)
      }
    }
    

    recover 将捕获未来执行中引发的异常,从而允许您返回包装在 Future 中的新结果,如文档所述:

    如果成功完成,recover 组合器会创建一个新的未来,它与原始未来保持相同的结果。如果没有,则将部分函数参数应用于原始未来失败的 Throwable。

    【讨论】:

    • Error(e.toString) 应该是Future(Error(e.toString))
    • 其实没有,如果你看到文档上的例子val purchase: Future[Int]recover是这样定义的:recover { case QuoteChangedException() =&gt; 0 },同时查找recover定义here,你会看到返回类型是已经是未来了。
    • 我无法测试类型,但发生此错误是因为Error 不是SentSmsResult 类型,您必须考虑recover 是否是您想要使用的类型,因为主要用途即使未来失败也提供结果,例如,如果有某种异常,您可能希望返回一个SentSmsResult,表示没有发送短信,然后稍后使用该结果,这就是@987654336 @ 方法强制执行。如果您不想这样做,则可以坚持使用 try/catch,但据我所知,这是期货的 scala 方式。
    • 实际上,我正在使用“return”,这就是为什么会这样。
    • 是的,但请记住,您返回的类型必须符合函数签名,如果您的签名返回Future[Int]recover 也必须返回Future[Int],在您的情况下我怀疑@ 987654340@ 不是SentSmsResult 类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    相关资源
    最近更新 更多