将Future[SomeObject]转换为json

将Future[SomeObject]转换为json,json,scala,playframework,playframework-json,Json,Scala,Playframework,Playframework Json,我正在使用scala并将域对象写入json。我使用Play的Json组合符,如下所示: implicit def opensHighlights: Writes[Option[OpensHighlights]] = ( (__ \ 'header).write[String] and (__ \ 'topDeviceForOpens).write[String] and (__ \ 'percentage).write[String] and (__ \ 'p

我正在使用scala并将域对象写入json。我使用Play的Json组合符,如下所示:

implicit def opensHighlights: Writes[Option[OpensHighlights]] =
  (
    (__ \ 'header).write[String] and
    (__ \ 'topDeviceForOpens).write[String] and
    (__ \ 'percentage).write[String] and
    (__ \ 'percentageOf).write[String])(opensMaybe => {
      val header = Messages("email.summary.highlights.device.opens")
      val percentageOf = Messages("email.summary.highlights.ofAll.opens")
      opensMaybe match {
        case Some(opens) => (
          header,
          deviceTypeName(opens.topDevice),
          Percentage(opens.opensOnThisDevice, opens.totalOpens).stringValue(),
          percentageOf)
        case None => (header, NotApplicable, "0.00", percentageOf)
      }
    })
def highlights: Future[Option[OpensHighlights]] = ...

def asyncJson = Action.async { request =>
    highlights.map { result =>
        Ok(Json.toJson(result))
    }
}
我正在一个更大的书写器中使用此书写器:

implicit def summaryHighlightsWrites: Writes[SummaryHighlights] = {
      (
        (__ \ "google").write[Either[GoogleError, GoogleHighlights]] and
        (__ \ "dateWithHighestClickToOpenRate").write[Option[DateHighlights]] and
        (__ \ "subjectLine").write[Option[SubjectLineHighlights]] and
        (__ \ "location").write[Option[LocationHighlights]] and
        (__ \ "link").write[Option[LinkHighlights]] and
        (__ \ "deviceForOpens").write[Option[OpensHighlights]] and
        (__ \ "deviceForClicks").write[Option[ClicksHighlights]])(summary => {
          val result = for {
            google <- summary.google
            dateRange <- summary.dateRange
            subjectLine <- summary.subjectLine
            location <- summary.location
            link <- summary.link
            opensDevice <- summary.opensDevice
            clicksDevice <- summary.clicksDevice
          } yield (google, dateRange, subjectLine, location, link, opensDevice, clicksDevice)

          Await.result(result, 10 seconds)
        })
    }
我需要这些字段都是未来的,因为它们有独立的来源,并且可以独立地失败/成功

我想删除这个明确的等待。我想把对未来的等待从
Summary Highlights Writes
转移到调用此编写器的其他代码段。就像一个游戏控制器


有什么帮助吗?谢谢

假设您有一个方法高亮显示,该方法返回一个
未来[Option[OpensHighlights]]
,并且您有一个隐式的
写入[Option[OpensHighlights]]
在范围中定义,您可以这样做:

implicit def opensHighlights: Writes[Option[OpensHighlights]] =
  (
    (__ \ 'header).write[String] and
    (__ \ 'topDeviceForOpens).write[String] and
    (__ \ 'percentage).write[String] and
    (__ \ 'percentageOf).write[String])(opensMaybe => {
      val header = Messages("email.summary.highlights.device.opens")
      val percentageOf = Messages("email.summary.highlights.ofAll.opens")
      opensMaybe match {
        case Some(opens) => (
          header,
          deviceTypeName(opens.topDevice),
          Percentage(opens.opensOnThisDevice, opens.totalOpens).stringValue(),
          percentageOf)
        case None => (header, NotApplicable, "0.00", percentageOf)
      }
    })
def highlights: Future[Option[OpensHighlights]] = ...

def asyncJson = Action.async { request =>
    highlights.map { result =>
        Ok(Json.toJson(result))
    }
}

Future[…]
必须映射到
Action.async
中返回的
Future[Result]
,它将专门处理
Future[Result]
s,而不是普通的
Result

假设您有一个方法
高亮显示
返回
Future[Option[OpensHighlights]]
如果在范围中定义了一个隐式的
写入[Option[OpensHighlights]]
,则可以执行以下操作:

implicit def opensHighlights: Writes[Option[OpensHighlights]] =
  (
    (__ \ 'header).write[String] and
    (__ \ 'topDeviceForOpens).write[String] and
    (__ \ 'percentage).write[String] and
    (__ \ 'percentageOf).write[String])(opensMaybe => {
      val header = Messages("email.summary.highlights.device.opens")
      val percentageOf = Messages("email.summary.highlights.ofAll.opens")
      opensMaybe match {
        case Some(opens) => (
          header,
          deviceTypeName(opens.topDevice),
          Percentage(opens.opensOnThisDevice, opens.totalOpens).stringValue(),
          percentageOf)
        case None => (header, NotApplicable, "0.00", percentageOf)
      }
    })
def highlights: Future[Option[OpensHighlights]] = ...

def asyncJson = Action.async { request =>
    highlights.map { result =>
        Ok(Json.toJson(result))
    }
}

Future[…]
必须映射到
Action.async
中返回的
Future[Result]
,它将专门处理
Future[Result]
s,而不是普通的
Result

假设您有一个方法
高亮显示
返回
Future[Option[OpensHighlights]]
如果在范围中定义了一个隐式的
写入[Option[OpensHighlights]]
,则可以执行以下操作:

implicit def opensHighlights: Writes[Option[OpensHighlights]] =
  (
    (__ \ 'header).write[String] and
    (__ \ 'topDeviceForOpens).write[String] and
    (__ \ 'percentage).write[String] and
    (__ \ 'percentageOf).write[String])(opensMaybe => {
      val header = Messages("email.summary.highlights.device.opens")
      val percentageOf = Messages("email.summary.highlights.ofAll.opens")
      opensMaybe match {
        case Some(opens) => (
          header,
          deviceTypeName(opens.topDevice),
          Percentage(opens.opensOnThisDevice, opens.totalOpens).stringValue(),
          percentageOf)
        case None => (header, NotApplicable, "0.00", percentageOf)
      }
    })
def highlights: Future[Option[OpensHighlights]] = ...

def asyncJson = Action.async { request =>
    highlights.map { result =>
        Ok(Json.toJson(result))
    }
}

Future[…]
必须映射到
Action.async
中返回的
Future[Result]
,它将专门处理
Future[Result]
s,而不是普通的
Result

假设您有一个方法
高亮显示
返回
Future[Option[OpensHighlights]]
如果在范围中定义了一个隐式的
写入[Option[OpensHighlights]]
,则可以执行以下操作:

implicit def opensHighlights: Writes[Option[OpensHighlights]] =
  (
    (__ \ 'header).write[String] and
    (__ \ 'topDeviceForOpens).write[String] and
    (__ \ 'percentage).write[String] and
    (__ \ 'percentageOf).write[String])(opensMaybe => {
      val header = Messages("email.summary.highlights.device.opens")
      val percentageOf = Messages("email.summary.highlights.ofAll.opens")
      opensMaybe match {
        case Some(opens) => (
          header,
          deviceTypeName(opens.topDevice),
          Percentage(opens.opensOnThisDevice, opens.totalOpens).stringValue(),
          percentageOf)
        case None => (header, NotApplicable, "0.00", percentageOf)
      }
    })
def highlights: Future[Option[OpensHighlights]] = ...

def asyncJson = Action.async { request =>
    highlights.map { result =>
        Ok(Json.toJson(result))
    }
}


Future[…]
必须映射到
Action中返回的
Future[Result]
。async
,它将专门处理
Future[Result]
s,而不是普通的
Result
s。为
Future
创建
写入
没有意义。你需要为你的问题提供更多的背景。
未来的
来自哪里,您在哪里使用它?我的猜测很可能是在一个需要
未来[结果]
的游戏控制器中,但我不知道你的问题。正如@LimbSoup所提到的,你不能将
未来
转换为Json。相反,您可以使用一个函数映射未来,并在该函数中将元组转换为json。然后你会有一个
Future[Json]
,你可以很容易地使用播放控制器(例如使用
Action.async
)是的,@LimbSoup,这是我的意图,将它提供给播放控制器。编译错误是什么?使用
Future
s的case类字段不是一个好主意。那只会造成一片混乱。为
未来
创造一个
是没有意义的。你需要为你的问题提供更多的背景。
未来的
来自哪里,您在哪里使用它?我的猜测很可能是在一个需要
未来[结果]
的游戏控制器中,但我不知道你的问题。正如@LimbSoup所提到的,你不能将
未来
转换为Json。相反,您可以使用一个函数映射未来,并在该函数中将元组转换为json。然后你会有一个
Future[Json]
,你可以很容易地使用播放控制器(例如使用
Action.async
)是的,@LimbSoup,这是我的意图,将它提供给播放控制器。编译错误是什么?使用
Future
s的case类字段不是一个好主意。那只会造成一片混乱。为
未来
创造一个
是没有意义的。你需要为你的问题提供更多的背景。
未来的
来自哪里,您在哪里使用它?我的猜测很可能是在一个需要
未来[结果]
的游戏控制器中,但我不知道你的问题。正如@LimbSoup所提到的,你不能将
未来
转换为Json。相反,您可以使用一个函数映射未来,并在该函数中将元组转换为json。然后你会有一个
Future[Json]
,你可以很容易地使用播放控制器(例如使用
Action.async
)是的,@LimbSoup,这是我的意图,将它提供给播放控制器。编译错误是什么?使用
Future
s的case类字段不是一个好主意。那只会造成一片混乱。为
未来
创造一个
是没有意义的。你需要为你的问题提供更多的背景。
未来的
来自哪里,您在哪里使用它?我的猜测很可能是在一个需要
未来[结果]
的游戏控制器中,但我不知道你的问题。正如@LimbSoup所提到的,你不能将
未来
转换为Json。相反,您可以使用一个函数映射未来,并在该函数中将元组转换为json。然后你会有一个
Future[Json]
,你可以很容易地使用播放控制器(例如使用
Action.async
)是的,@LimbSoup,这是我的意图,将它提供给播放控制器。编译错误是什么?使用
Future
s的case类字段不是一个好主意。那只会造成一片混乱。