2017-01-31 12 views
0

Я смотрел какой-то проект Scala с открытым исходным кодом. и я увидел, что некоторые из них делают что-то вроде:Идиоматический способ блокировки асинхронных операций

abstract class Foo{ 

def create(implicit ex: ExecutionContextExecutor): Seq[ResultSet] = { 
    Await.result(createAsync(), timeout) 
    } 

    def createAsync()(implicit ex: ExecutionContextExecutor): Future[Seq[ResultSet]] = //implementation 

... more like those 
} 

есть ли какой-либо преимущество/недостаток для вызова каждого метода с

(неявным например: ExecutionContextExecutor) параметра, а не передавая ExecutionContextExecutor в класс:

abstract class Foo(implicit ex: ExecutionContextExecutor){ 

def create(timeout: FiniteDuration): Seq[ResultSet] = { 
    Await.result(createAsync(), timeout) 
    } 

    def createAsync(): Future[Seq[ResultSet]] = //implementation 

... more like those 
} 

Есть ли предпочтительный вариант?

+0

Можете изменить название? Это реальный вопрос, который принесет пользу новичкам на языке, но я пришел сюда, потому что название читалось так, как будто это было бы прежде всего частью мнения. Или я просто слишком много читаю, потому что я здесь слишком долго ...? – wheaties

+0

@wheaties, что вы предлагаете? – igx

+0

Не знаю, «Должен ли ExecutionContext быть на методе или объекте?» также звучит очень упрямо. «Выгода ExecutionContext для метода против объекта?» Gah ... – wheaties

ответ

1

Прежний подход дает вам больше гибкости в отношении того, где будет запланировано выполнение createAsync, поскольку каждый раз, когда вы можете принять решение о том, к какому ExecutionContext вы хотите пройти, вопрос: нужна ли вам такая гибкость? Я нахожу, что в большинстве случаев достаточно одного ExecutionContext, но это действительно вопрос в каждом конкретном случае.

В общем, первый фрагмент ужасен ИМО. Обнаружение синхронной обертки, которая блокирует асинхронную операцию, обычно является признаком запаха кода, и такой код плохо масштабируется.

+0

Я предполагаю, что вы имели в виду, что первый вариант более гибкий, поскольку executeContext передается как параметр в каждом вызове. Я бы не подумал об этом как о запахе кода, так как они дают вам возможность блокирующего вызова. – igx

+0

@igx Блокировка вызовов при асинхронных операциях не масштабируется. Мне лично не нравится видеть такой код. –

+0

Я только что видел в больших проектах с открытым исходным кодом, таких как phantom https://github.com/outworkers/phantom/blob/752dda5c4493f236a8d304cc0fe57b0660af69db/phantom-dsl/src/main/scala/com/outworkers/phantom/database/Database.scala – igx