从Future [List [A]]获得未来头脑的首选方式

时间:2015-11-03 06:57:25

标签: scala future

所以......让我说我有一个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>

3 个答案:

答案 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的来电者可以处理SuccessFailure

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(""))