Size: a a a

2021 June 02

BP

Bogdan Panchenko in Kotlin Start
https://kotlinlang.org/docs/flow.html#flow-context начало

https://kotlinlang.org/docs/flow.html#flow-context вот оператор который нужно использовать перед collectom
источник

BP

Bogdan Panchenko in Kotlin Start
хотя нет. stateFlow.value = newValue должен взять контекст где исполняется.

Но честно пока не вижу смысла в этом подходе и почему этот flow находиться во ViewModel (если мы про TornadoFX VIewModel).

мне кажеться тут EventBus от торнады нормально бы зашел
источник

a

awawa in Kotlin Start
В смысле withContext? А зачем? Если я создаю корутин скоуп с диспатчером на JavaFX потоке. Мне на нём и надо коллектить, потому что UI обновляется. А емиты я делаю с IO контекстом.
источник

a

awawa in Kotlin Start
Вернее не сами эмиты, а в принципе БД операции на IO происходят и оттуда эмитятся значения
источник

a

awawa in Kotlin Start
Про EventBus не читал, но если оно от TornadoFX, то во-первых, не хочется в БД затягивать части UI фреймворка, а во-вторых, у меня может не только TornadoFX юзаться. У меня также предусмотрена работа через чисто терминальный интерфейс с UI на Lanterna
источник

BP

Bogdan Panchenko in Kotlin Start
ну если мы берем чесный Flow то вот , flow холодный, и если не сделать переключения контекста то emit будет выполняться в контексте collect.

Если вы делаете stateFlow.value = newValue - все ок
источник

BP

Bogdan Panchenko in Kotlin Start
у вас один проект но не хочеться мешать UI и другую логику ? (для синхронизации мыслей)

Тогда нормально, только отмену продумать нужно, ну и нужно учесть что onDock может выполнятся несколько раз
источник

a

awawa in Kotlin Start
В общем да. Хотелось бы строить так, чтобы я мог заменить UI фреймворк без переписывания остальной логики.
источник

a

awawa in Kotlin Start
А, ну это если я делаю через  flow { ... }, то внутри этого блока нельзя менять контекст, как я понял. Но у меня другая ситуация, у меня есть MutableStateFlow. И я делаю что-то типа:

someScope.launch(Dispatchers.IO) {
   val newData = calculateNewData()
   someFlow.emit(newData)
}
...

otherScope.launch(Dispatchers.JavaFX) {
   someFlow.collect {...}
}


Во всяком случае эксепшены не падают.

P.S. Я в итоге сохраняю инстанс джобы, которая создаётся в onDock и делаю на ней cancel в onUndock. Сначала сделал cancel на скоупе, но тут как раз при повторном вызове onDock уже launch не работает.
источник

BP

Bogdan Panchenko in Kotlin Start
> someFlow.emit(newData)

а почему не someFlow.value = newData. не уверен что первый вариант равносилен второму

> Я в итоге сохраняю инстанс джобы,

так и нужно

> но тут как раз при повторном вызове onDock уже launch не работает

что-то странное

PS:  а хотя скорей всего скоуп полностью закрылся, нужно новый или supervisor job, или саму View объявить контесктом (не уверен в данном варианте)
источник

BP

Bogdan Panchenko in Kotlin Start
> не уверен что первый вариант равносилен второму

можно проверить, в доке как раз есть пример)
источник

BP

Bogdan Panchenko in Kotlin Start
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-state-flow/index.html

> State flow never completes. A call to Flow.collect on a state flow never completes normally, and neither does a coroutine started by the Flow.launchIn function. An active collector of a state flow is called a subscriber.
источник

BP

Bogdan Panchenko in Kotlin Start
> > не уверен что первый вариант равносилен второму

тоже самое. Проверил
источник

a

awawa in Kotlin Start
Только someFlow.value = newData - не саспенд функция и это можно делать вне корутины. Тоже проверил)
источник

BP

Bogdan Panchenko in Kotlin Start
да в этом и смысл, мне просто казалось что  emit ведет себя стандартно (он не переопределен).

А по поводу почему повторно не запускается, нужно понять почему, для начала убедиться что вызовы onUndock и onDock имеют одинаковое количество (мало ли). Также написать минимальный пример без торнады, если повторяется то уже разбираемся почему (не думаю что проблема в торнаде) .

Я лично думаю что скоуп одноразовый и после отмены он не запустит новую корутину
источник

BP

Bogdan Panchenko in Kotlin Start
источник

a

awawa in Kotlin Start
Да, я проверил. Ну и ещё где-то тоже вычитал, что если канселить скоуп, то уже не лаунчится на нём ничего. Не помню где, правда
источник

BP

Bogdan Panchenko in Kotlin Start
в доке должно быть, Это называется кооперативная отмена. Если хотяб одна задача завершилась не удачно остальные тоже не стоит ждать
источник

BP

Bogdan Panchenko in Kotlin Start
отмена Job прокидывается к родительскому Scope
источник

L

Lessej in Kotlin Start
Господа, подскажите, вникаю в котлин. Вот в этом примере
data class City(val name: String) {
   override fun toString() = name
}

почему написано override? этот
override
к чему относится?
источник