def getCommentIds(
commentTargetId: Long,
sortOrder: CommentOrderEnum): Future[Seq[CommentStatsBO]]
def getCommentDetail(commentId: Long): Future[Option[CommentDetailDTO]]
def getCommentListWithDetail(
targetId: Long,
sortOrder: CommentOrderEnum,
page: Int): Future[Seq[CommentDetailDTO]] = {
commentModel.getCommentIds(targetId, sortOrder).flatMap {
commentStatsBOSeq =>
Future.traverse(commentStatsBOSeq) { commentStatsBO =>
// commentDetail is a Future[Option[T]]
val commentDetail = getCommentDetail(commentStatsBO.iId)
commentDetail.map(commentOpt =>
commentOpt
// merge the stat info into the comment detail
.map(_.copy(replyCount = Some(commentStatsBO.replyCount)))
.getOrElse(CommentDetailDTO))
}
}
}
case class CommentDetailDTO(
id: Long,
author: JsObject,
detail: CommentDetail,
replyCount: Option[Int] = None
)
首先,該函式getCommentIds回傳一個 CommentStatsBO 序列,然后遍歷它并嘗試獲取每個評論的詳細資訊。問題來了,getCommentDetail回傳一個包含選項的 Future ,因為可能找不到評論,在這種情況下,如何過濾那些選項為 None 的?我試過getOrElse ,但不知道如何定義一個空物件,就像Json.obj()因為case class不支持一樣。謝謝!
uj5u.com熱心網友回復:
不要試圖同時做太多事情,而是逐步構建您需要的解決方案。
如果你做一個簡單的Future.traverseusing justgetCommentDetail你會得到一個Future[Seq[Option[CommentDetailDTO]]] 然后你可以map使用collect它Seq來洗掉Option
def getCommentListWithDetail(
targetId: Long,
sortOrder: CommentOrderEnum,
page: Int
): Future[Seq[CommentDetailDTO]] =
commentModel.getCommentIds(targetId, sortOrder).flatMap { commentStatsBOSeq =>
Future.traverse(commentStatsBOSeq) { commentStatsBO =>
getCommentDetail(commentStatsBO.iId)
} map { commentOptionalDetails =>
commentOptionalDetails.collect {
case Some(commentDetail) => commentDetail
}
}
}
或者,如果您使用貓,則可以使用traverseFilter
import cats.syntax.all._
def getCommentListWithDetail(
targetId: Long,
sortOrder: CommentOrderEnum,
page: Int
): Future[Seq[CommentDetailDTO]] =
commentModel.getCommentIds(targetId, sortOrder).flatMap { commentStatsBOSeq =>
commentStatsBOSeq.traverseFilter(getCommentDetail)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344794.html
