2015-10-01 25 views
0

开始学习scala并为异步执行设计/实现。我的问题是如何设计API(然后调用)它们以返回Unit的操作,但可能不会马上。例如,在下面的代码片段中,该函数(使用Slick 3.0)将用户插入数据库。 Unit是这个函数的正确返回类型,如果是这样,那么调用者怎么知道新插入的用户是否/何时成功?如何使用期货设计和调用Scala API

override def insertOrUpdate(entity: User): Unit = { 
    database.run(users.insertOrUpdate(entity)) 
} 

例如,如果异步上述执行和呼叫者看起来像

//create and insert new user with id = 7 
val newUser = User(7, "someName") 
userRepo.insertOrUpdate(newUser) 

如何调用者知道它是否是安全的

userRepo.findById(7) 

在单元测试,我知道如果我通过findById调用立即跟进插入调用,findById将不会返回任何内容,但如果我在插入和调用之间引入一些延迟,它会找到新用户。总结一下,为一个函数设计API的正确方法是异步执行的,但没有自然的返回值来包装在Future中?

回答

3

通常在使用Future s时,您需要通过返回的Future上的方法进行任何进一步处理。例如:

val newUser = User(7, "someName") 
val future = userRepo.insertOrUpdate(newUser) 
future.onSuccess { outcome => // Here, 'outcome' will hold whatever was contained in the Future - Unit in your description above. 
    val storedUser = userRepo.findById(7) // This will only execute once the future completes (successfully). 
    ... 
} 

有大量的其他有用的方法用于操作一个Future(或它们的集合),如“onFailure处”,“恢复”,“地图”和“flatMap”。

尽量不要在Future等到尽可能晚地 - 最好是让玩家或喷雾或任何其他的框架,你可能碰巧使用的是照顾你(见here用于播放的文件上这样做,例如)。

最后,就你的数据库调用插入而言,我会考虑让调用返回至少一个布尔值,或者更好的是新条目插入的主键,而不是Unit

相关问题