2016-07-06 72 views
2

我做这样的事情:过滤里面换理解与期货

(for { 
    data <- Future(getData) 
    updated = makeChanges(data) if updated != data 
    _ <- Future(saveUpdates(updated)) 
    _ <- Future(recordTransaction) 
} yield()).recover { case e: NoSuchElementException =>() } 

当过滤器并不满意,它跳过剩下的两个步骤,通过抛出一个异常(不好),那(好!)我必须抓住并处理结束。流量控制使用异常不会觉得太高雅了我,虽然,我从明显的不知道是否有更好的方式来做到这一点,除了 - 与if语句包裹的全部剩余线路:

_ <- if(updated != data) Future(saveUpdates(updated)) else Future.successful(()) 
    _ <- if(updated != data) ... 
+0

如果你可以改变makeChanges返回的元组(改为:更新布尔:数据)就可以了,你能模式匹配,并决定哪些行动在这种情况下。它会使它更清洁 –

+0

@LouisF。不明白你的意思。我可以很容易地在'updated!= data'上模式匹配,但不知道如何使用它来使其更清洁。用'match ... case'剪掉上一个剪下的'if ... else ..'? – Dima

回答

2

我不假设你可以避免使用理解的流量控制的异常,那么你可以使用嵌套表达式而不是过滤器,并手动处理条件给scala它所需的返回类型,以防条件不满足:

for { 
    data <- Future(data) 
    updated = makeChanges(data) 
    res = { 
    if (updated != data) Future.successful(()) 
    else for { 
     _ <- Future(saveUpdates(updated)) 
     _ <- Future(recordTransaction) 
    } yield() 
    } 
} yield res 

但是,对于这个例子,我会去简单的方法,并放弃理解,导致更多可读的代码(可能是你的真实使用情况是比较复杂的,虽然):

Future(data).flatMap(d => { 
    val updated = makeChanges(d) 
    if(updated == d) Future.successful(()) 
    else Future(saveUpdates(updated)).map(_ => recordTransaction) 
}) 
+0

是的,我自己并不是一个理解力强的粉丝,但在这种特殊情况下,我认为你的建议根本不是“更具可读性”:(如果有什么我不喜欢过度使用理解,这是过度的嵌套。 – Dima