Scala中通过链式调用Futures计算用户总分的实现求助
Implementing
getTotalScore for Async Score Calculation Hey there! Let's tackle this getTotalScore implementation step by step. Since all our data retrieval methods return Futures, we need to properly compose these asynchronous operations to keep things efficient and avoid unnecessary blocking.
Core Logic Breakdown
Here's what we need to do for each user in the class:
- Fetch all their subjects, filtering only those marked
includeForTotal = true - Sum up the scores for those eligible subjects
- Add the user's bonus score to that sum
- Wrap everything into a
UserScoreinstance, then collect all results for the class
The Implementation
We can use Scala's for comprehensions to make the async flow read like synchronous code, and Future.traverse to handle converting a sequence of users into a sequence of their computed scores (wrapped in a single Future):
def getTotalScore(classID: Int): Future[Seq[UserScore]] = { // First, get all users in the target class getUsers(classID).flatMap { users => // Traverse each user to compute their total score asynchronously Future.traverse(users) { user => val userId = user.id for { // Fetch the user's subjects and filter those that count towards the total subjects <- getSubjects(userId) includedSubjects = subjects.filter(_.includeForTotal) // Fetch scores for all included subjects, then sum them up subjectScores <- Future.sequence(includedSubjects.map(subject => getScore(subject.id, userId))) subjectTotal = subjectScores.sum // Fetch the bonus score and calculate the final total bonus <- getBonusScore(userId) finalTotal = subjectTotal + bonus } yield UserScore(userId, finalTotal) } } }
Key Details Explained
Future.traverse: This is a handy shortcut that combinesmapandFuture.sequence—it takes aSeq[A]and a functionA => Future[B], then returns aFuture[Seq[B]]. Perfect for processing multiple users in parallel.forComprehension: Lets us chain multipleFutureoperations sequentially without nestedflatMapcalls, making the code much easier to read.Future.sequence: Converts aSeq[Future[Int]](one future per subject score) into aFuture[Seq[Int]], so we can safely sum all the scores once they're all available.
Expected Output
When you run the code, you'll see:
class1: List(UserScore(1,90), UserScore(2,95)) class2: List(UserScore(1,90), UserScore(2,95))
- User 1: 60 (subject 1 score) + 30 (bonus) = 90
- User 2:75 (subject 1 score) +20 (bonus) =95
内容的提问来源于stack exchange,提问作者Yatheesha
相关产品推荐
相关产品推荐

