2014-09-24 27 views
0

我正在Scala寫一個play 2.3應用程序。 我使用mongoDB數據庫和ReactiveMongo驅動程序。 我調用讀取/寫入/更新數據庫中日期的方法返回Future [Option [T]]。 我的問題是這樣的:如果我有一個方法,第一次更新文件,並在閱讀更新後的文件,我需要一個onComplete語句或不? 例如:瞭解未來[Option [T]] reactiveMongo

def updatePasswordInfo(user: LoginUser,info: PasswordInfo): scala.concurrent.Future[Option[BasicProfile]] = { 
    import LoginUser.passwordInfoFormat //import the formatter 
    //the document query 
    val query = Json.obj("providerId" -> user.providerId, 
         "userId" -> user.userId 
         ) 
    val newPassword = Json.obj("passswordInfo" -> info)// the new password 
    //search if the user exists and 
    val future = UserServiceLogin.update(query, newPassword) //update the document 
    for { 
     user <- UserServiceLogin.find(query).one 
    } yield user //return the new LoginUser 

    } 

是正確的O I前需要使用的onComplete語句中使用UserServicelogin.find(query).one聲明?

回答

1

您有概念錯誤。在檢索用戶之前,您並未等待更新完成,因此實際上最終可能會在更新之前檢索用戶。

修復的方法是非常簡單的:

for { 
    _ <- UserServiceLogin.update(query, newPassword) 
    user <- UserServiceLogin.find(query).one 
} yield user 

期貨在換comprenehsion的sequecenced,所以你總是返回更新的用戶。

之所以這個作品,就是換理解desugars到

UserServiceLogin.update(query, newPassword).flatMap { _ => 
    UserServiceLogin.find(query).one.map { user => 
    user 
    } 
} 

所以執行find方法後,才update方法取得了成功。

+0

爲什麼這個工作?爲什麼第一條語句在第一條語句完成後執行? – 2014-09-24 13:42:46

+1

@albertoadami,看我更新的答案 – 2014-09-24 13:45:59

0

你有很多選項可供選擇:

  • andThen
  • 地圖
  • 的理解

隨着map你會得到在執行的最後Future結果鏈。用andThen您將得到您應用andThen的第一個Future的結果。

對於您的使用案例formap操作都很好。我會用map這樣的:

def updatePasswordInfo(user: LoginUser,info: PasswordInfo): scala.concurrent.Future[Option[BasicProfile]] = { 
    import LoginUser.passwordInfoFormat //import the formatter 
    //the document query 
    val query = Json.obj("providerId" -> user.providerId, 
         "userId" -> user.userId 
         ) 
    val newPassword = Json.obj("passswordInfo" -> info)// the new password 
    //search if the user exists and 
    val future = UserServiceLogin.update(query, newPassword) //update the document 
    future.map(x => UserServiceLogin.find(query).one) 
    } 

參考文獻:

[1] http://www.scala-lang.org/api/current/#scala.concurrent.Future

[2] http://docs.scala-lang.org/sips/completed/futures-promises.html