所以......让我说我有一个Future[ List[ A ] ]
,我想要的是一个Future
,其中包含first element
list
包含的Future
def getFirstByName( name: String ): Future[ A ] = {
val aListFuture = ...
// somehow got the future of list of all A's for this name
// Now how do I return a Future[ A ] contaning the head of said list
}
1}}。
考虑到这是db访问层的一部分,这可能是首选的方法吗?
Considering this is a part of the db access layer what can be the preferred way of doing this ?
此问题的重点更多地放在val aFuture = aListFuture.map(l => l.head)
上。
我们可以执行类似def getFirstByName( name: String ): Future[ A ] = {
// somehow got the future of list of all A's for this name
val aListFuture = ...
aListFuture map( _.head ) match {
case Some( t: Try[ A ] ) => t match {
case Success( a: A ) => Promise.successful( a ).future
case Failure( e: NoSuchElementException ) => Promise.failed( DbNotFound ).future
case Failure( e ) => Promise.failed( e ).future
}
case _ => Promise.failed( new Exception( "Some unexplained exception" ) ).future
}
}
之类的操作,但如果列表为空,该怎么办?
在这个问题中,我真正想要的是"如何设计可预测的解决方案?"。
除了使用域特定异常优雅地失败之外,还有其他选择吗?如果不是如何实现这样的失败?
我目前正在使用以下脏技巧,
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
<div class="form-group {{ $errors->has('name') ? 'has-error' : '' }} control-required">
{!! Form::label('title', 'Title') !!}<span class="mand_star"> *</span>
{!! Form::text('title', isset($news->title) ? $news->title : \Input::old('title'), [
'class' => 'form-control',
'placeholder' => 'News Title',
'required' => 'required'
]) !!}
<span class="error_span"> {{ $errors->first('title') }}</span>
</div>
</div>
答案 0 :(得分:3)
试试这个:
val futureOfHead = aListFuture.map (_.head)
对于将来返回空列表的情况,您可以提供默认值:
val DefaultValue = ...
val futureOfHead = aListFuture.map (_.headOption.getOrElse(DefaultValue))
另一种选择:
val futureOfHead = aListFuture.map (_.headOption.getOrElse(throw new RuntimeException("db layer exception"))
答案 1 :(得分:1)
您可以使用map
然后使用head
。
def map[S](f: (T) ⇒ S)(implicit executor: ExecutionContext): Future[S]
通过将函数应用于此未来的成功结果来创造新的未来。如果这个未来以异常完成,那么新的未来也将包含此异常。
val aListFuture = futureList.map(l => l.head)
此dao的来电者可以处理Success
和Failure
future.onComplete( {
case Success(result) => ..
case Failure(err) => .. //if head is empty you'll get java.util.NoSuchElementException
}
答案 2 :(得分:1)
所有的回答都是正确的,但如果适合您的问题,可能会有一个不那么容易出错的解决方案:
val aListFuture = futureList.map(l => l.headOption)
返回Future [Option [A]],而不是通过模式匹配检查。
此外,如果您想要并拥有默认值,您可以使用:
val aListFuture = futureList.map(l => l.headOption.getOrElse(""))