Сопрограммы во вложенных областях

#java #kotlin #kotlin-coroutines #kotlin-flow

#java #kotlin #kotlin-сопрограммы #kotlin-flow

Вопрос:

Я пишу библиотеку Android, и у меня есть ситуация (ОЧЕНЬ упрощенная здесь для примера) с интерфейсом, в котором мне нужно создать функцию suspended , чтобы иметь возможность вызывать Flow.collect ее.

 interface Executor {
   suspend fun <T> execute(flow: Flow<T>)
}

class MyExecutor(): Executor {
   override suspend fun <T> execute(flow: Flow<T>) {
      flow.collect {
         println("execution obtained $it")
      }
   }
}

class A(val scope: CoroutineScope, val classB: B, val executor: Executor) {
   fun executeCommand() {
      scope.launch {
         val command = classB.getCommand()
         executor.execute(command)
      }
   }
}

class B() {
   fun getCommand(): Flow<Int> = flowOf(1)
}
 

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь использовать эту библиотеку из тестового приложения, написанного на Java, я не могу правильно реализовать Executor интерфейс, учитывая его приостановленную функцию.

Есть ли у вас какие-либо предложения о том, как это сделать?

p.s. Решением было бы создать execute обычную функцию и предоставить MyExecutor a CoroutineScope в конструкторе, но даже если мне удастся создать один элемент для всего приложения, это все равно будет «вложенная» область видимости, в результате чего разные работники будут обрабатывать процесс. Хотя я не уверен, насколько это неправильно, это звучит неправильно

 class MyExecutor(val scope: CoroutineScope): Executor {
   override fun <T> execute(flow: Flow<T>) {
      scope.launch {
         flow.collect {
            println("execution obtained $it")
         }
      }
   }
}
 

Комментарии:

1. Если эта библиотека должна использоваться в Java, я бы предоставил «стандартный» не-сопрограммный API с функциями сопрограммы, предоставляемыми через функции расширения. Никто не хочет работать с контекстами и потоками сопрограмм в коде Java.

2. Спасибо за совет Tenfounr04, не могли бы вы, возможно, подробнее рассказать о том, как добиться этого с помощью функций расширения (принимая во внимание, что внутренне я бы все равно не стал использовать его «как если бы» он был приостановлен)?

3. Я думаю, что типичные асинхронные API в Java используют систему обратного вызова и ExecutorService для обработки асинхронной работы и выполнения обратного вызова в вызывающем потоке.