2016-07-06 3 views
2

я делаю что-то вроде этого:фильтрация внутри для-понимания с фьючерсами

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

Если фильтр не удовлетворен, он пропустит оставшиеся два шага, бросая исключение (не хорошо), что (хорошо!) Я должен поймать и обработать в конце. Использование исключений для управления потоком не чувствует себя слишком элегантно ко мне, хотя, мне интересно, если есть лучший способ сделать это, кроме очевидного - оборачивать все остальные строки с, если заявление:

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

Если вы можете изменить makeChanges вернуть кортеж (изменено: Boolean, обновление: Data) вы могли бы сопоставление с образцом на нем и решить, какие действия возьмите в этом случае. Это сделало бы его чистым –

+0

@LouisF. не уверен о чем ты. Я могу сопоставлять совпадение на 'updated! = Data' так же легко, но не уверен, как использовать его, чтобы сделать его более чистым. Замените 'if ... else ..' в последнем, отрезаемом' match ... case'? – 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