2016-08-22 20 views
4

私の方法1では、Option(result1)を返す別のメソッド2を非同期的に呼び出す必要があります。それより、result1が空の場合は別のメソッド3を非同期に呼び出す必要がありますが、result1が空でない場合は返す必要があります。ここScala Future - 理解のため、ミックスシンクと非同期

は方法である:

def signIn(username: String): Future[User] = { 
    for { 
     foundUser <- userService.findByUsername(username) // this method returns Future[Option[User]], 
     // foundUser is Option[User] 
     user <- if (foundUser.isEmpty) { 
     val newUser = User(username = "User123") 
     userService.create(newUser).map(Some(_)) // this method returns Future[Option[User]] 
     } 
     else 
     // Here I want to return just foundUser, of course, it is not possible. 
     // IS THIS APPROACH CORRECT?? DOES THIS LINE CREATE ASYNCHRONOUS CALL?   
     Future.successful(foundUser) 
    } yield user 
    } 

質問は:

Future.successful(foundUser) - このアプローチは、上記のコードで正しいですか?この行は非同期呼び出しを作成しますか?もしそうなら、それを避ける方法は?私はすでにを見つけました。ユーザは非同期で、すでにフェッチされた値を返すだけで非同期呼び出しを追加したくありません。

答えて

4

Future.successfulExecutionContextに追加の機能をキューイングしません。それだけで完成Future[T]を作成するためにPromise[T]を使用しています:サイドノートとして

/** Creates an already completed Future with the specified result. 
    * 
    * @tparam T  the type of the value in the future 
    * @param result the given successful value 
    * @return   the newly created `Future` instance 
    */ 
    def successful[T](result: T): Future[T] = Promise.successful(result).future 

、あなたがOption.foldを使用して定型の量を減らすことができます。

def signIn(username: String): Future[User] = 
    userService 
    .findByUsername(username) 
    .flatMap(_.fold(userService.create(User(username = "User123")))(Future.successful(_)) 
+0

は右、私が代わりにFuture.successful(foundUser)の将来{foundUser}を記述した場合、それは非同期で実行される、方法であなたに@Yuval Itzchakov – Teimuraz

+0

に感謝しますか? – Teimuraz

+0

@moreoはい、それは 'ExecutionContext'の関数のキューイングを引き起こします。 –

1

@Yuval Itzchakovは、あなたの質問に答え、しかしとしてサイドノートでは、flatMapをパターンマッチングで直接使用したい場合があります。私はpersonnallyそれがより読み見つける:

def signIn(username: String): Future[User] = 
    userService.findByUsername(username) 
    .flatMap { 
     case Some(user) => Future.successful(user) 
     case _ => userService.create(User(username = "User123")) 
    } 
+0

ありがとう、私はflatMapで最初にそれをimpelemtedしましたが、ここの私の例は、私の元のメソッドに比べて非常に単純化されています、私は多くのネストされたフラットマップ/マップを持っていたので、私は理解のためにそれを書き直すことにしました – Teimuraz

+0

センス:) –

関連する問題