Size: a a a

Kotlin Community

2019 November 01

AM

Andrew Mikhaylov in Kotlin Community
Igor
то есть фактически саспенд должен идти с терминальными операциями верно?
Не обязательно, у вас и .map может оказаться тяжёлым.
источник

QH

Quantum Harmonizer in Kotlin Community
разве map работает не как у сиквенса?
источник

I

Igor in Kotlin Community
Konstantin Zolotov
Фактически создание самого flow — легкая операция. Если сильно упрощенно, то это всего лишь создание некоторого количества объектов, там нечего саспендить. А вот когда на него подпишутся, то будут выполняться операторы flow и там уже неизвестно что будет.
спасибо, сейчас пример сделаю для обсуждения
источник

AM

Andrew Mikhaylov in Kotlin Community
Quantum Harmonizer
разве map работает не как у сиквенса?
Как у сиквенса, да. Но его параметр -- suspend.
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html
источник

LS

Lev Shagalov in Kotlin Community
Alexander Nozik
Вообще, я тут занимаюсь схожей с твой задачей. И мне стало очень хорошо, когда я просто отказался от JS фреймворков. Делаю на голом Kotlin-JS и мне сразу хорошо и удобно. Месяц бился над поиском нормальной либы на JS/TS, потом сам написал в 50 строчек и работает на ура.
У меня довольно навороченный фронт. Карты, анимация, рюшечки хотят.
источник

LS

Lev Shagalov in Kotlin Community
Меня как раз таки vue с openlayers спасают
источник

QH

Quantum Harmonizer in Kotlin Community
А, да, логично.
источник

I

Igor in Kotlin Community
Вот такой пример, нужен ли здесь suspend?                                             viewModelScope.launch {
           interactor.listenForUpdates().collect()
       }

fun listenForUpdates(): Flow<Int> {
           return repository.oneChannel.asFlow()
               .combine(twoChannel.asFlow()) { i,_ -> i}
               .map { updateUi(it) }
}
источник

VP

Vladimir Petrakovich in Kotlin Community
Igor
Вот такой пример, нужен ли здесь suspend?                                             viewModelScope.launch {
           interactor.listenForUpdates().collect()
       }

fun listenForUpdates(): Flow<Int> {
           return repository.oneChannel.asFlow()
               .combine(twoChannel.asFlow()) { i,_ -> i}
               .map { updateUi(it) }
}
Если функция только связывает потоки данных, ей не надо быть suspend.
И как минимум ей не надо быть suspend, если компилятор не требует.
источник

MM

Maxim Motorniy in Kotlin Community
Igor
Вот такой пример, нужен ли здесь suspend?                                             viewModelScope.launch {
           interactor.listenForUpdates().collect()
       }

fun listenForUpdates(): Flow<Int> {
           return repository.oneChannel.asFlow()
               .combine(twoChannel.asFlow()) { i,_ -> i}
               .map { updateUi(it) }
}
если продолжать аналогии с тасканием ящиков то получается что для выполнения работы надо
1) создать план действий, т.е. грубо говоря, кто, откуда, куда, сколько и как часто будет носить, это и есть создание Flow. Сама по себе операция вроде не тяжёлая, делать это через suspend большого смысла вроде нет.
2) непосредственная переноска тяжестей, с некоторыми преобразованиями, типа, перепаковать c одних ящиков в другие (map) и прочее. Тут необходимо понимать, что количество работников ограниченное, и на кассе ещё и людям отвечать надо что то. Поэтому всё делается через suspend внутри корутин скоупа. Грузчик как бы несёт ящик, но если надо отвлечся - отвечает людям на кассе, время от времени перекуривает, а затем продолжает выполнять перемещение тяжестей. Это наш .collect {} который запускает процесс подготовленный в первом пункте.
Т.е. если мы добавим suspend к функции что возвращает флоу мы просто сделаем неблокирующей функцию, которая создает сам флоу, сам план действий, что само по себе не должно занимать много процессорного времени.
Поправьте меня, пожалуйста, если где то ошибся.
источник

I

Igor in Kotlin Community
Vladimir Petrakovich
Если функция только связывает потоки данных, ей не надо быть suspend.
И как минимум ей не надо быть suspend, если компилятор не требует.
спасибо, насчет компилятора согласен
источник

I

Igor in Kotlin Community
Maxim Motorniy
если продолжать аналогии с тасканием ящиков то получается что для выполнения работы надо
1) создать план действий, т.е. грубо говоря, кто, откуда, куда, сколько и как часто будет носить, это и есть создание Flow. Сама по себе операция вроде не тяжёлая, делать это через suspend большого смысла вроде нет.
2) непосредственная переноска тяжестей, с некоторыми преобразованиями, типа, перепаковать c одних ящиков в другие (map) и прочее. Тут необходимо понимать, что количество работников ограниченное, и на кассе ещё и людям отвечать надо что то. Поэтому всё делается через suspend внутри корутин скоупа. Грузчик как бы несёт ящик, но если надо отвлечся - отвечает людям на кассе, время от времени перекуривает, а затем продолжает выполнять перемещение тяжестей. Это наш .collect {} который запускает процесс подготовленный в первом пункте.
Т.е. если мы добавим suspend к функции что возвращает флоу мы просто сделаем неблокирующей функцию, которая создает сам флоу, сам план действий, что само по себе не должно занимать много процессорного времени.
Поправьте меня, пожалуйста, если где то ошибся.
спасибо, аналогия хорошая, но все это не так очевидно, так как пример упрощаю, в реальном боев коде все может быть куда запутанее, и сложно может быть определить где надо, а где нет, только полагаться на компилятор
источник

GM

Gerr Mes in Kotlin Community
Dmitry Sapronov
А кто ещё?
Clojure/ClojureJS, последний даже вроде раньше нарисовался чем KotlinJS
источник

RI

Ruslan Ibragimov in Kotlin Community
Gerr Mes
Clojure/ClojureJS, последний даже вроде раньше нарисовался чем KotlinJS
Clojure/Native?
источник

GM

Gerr Mes in Kotlin Community
Кажись нет такого :)
источник

QH

Quantum Harmonizer in Kotlin Community
там CLR зато есть, да
источник

Н

Никита ✓ in Kotlin Community
А как идеоматичнее сделать:
Есть класс pojo, у которого есть nullable поле isBigList:Boolean? в конструкторе.
Хочу переделать, что бы поле получалось не нулабельным при помощи экстеншена:
fun Boolean?.falseIfNull() = this ?: false
И есть 2 варианта:
1й - иметь метод fun isBigList() = isBigList.falseIfNull()
2й вариант - сделать через переменную:
val bigList: Boolean
       get() = isBigList.falseIfNull()
Какой вариант правильнее и красивее по вашему?
источник

AO

Alexey Otts in Kotlin Community
Никита ✓
А как идеоматичнее сделать:
Есть класс pojo, у которого есть nullable поле isBigList:Boolean? в конструкторе.
Хочу переделать, что бы поле получалось не нулабельным при помощи экстеншена:
fun Boolean?.falseIfNull() = this ?: false
И есть 2 варианта:
1й - иметь метод fun isBigList() = isBigList.falseIfNull()
2й вариант - сделать через переменную:
val bigList: Boolean
       get() = isBigList.falseIfNull()
Какой вариант правильнее и красивее по вашему?
Либо сделать неопциональным и в месте создания явно прописывать false, либо когда получаешь явно говорить какой дефолт
Оба твои экстеншена выглядят избыточно
источник

Н

Никита ✓ in Kotlin Community
Т.е. лучше это всё убрать что напридумывал и дёргать непосредственно nullable переменную, я правильно понял?
источник

QH

Quantum Harmonizer in Kotlin Community
smthIfNull это же ?: smth
источник