Всем здравствуйте. Мне стало любопытно как в композе правильно/канонично обрабатывать

следующую ситуацию:
Есть предположим кнопка, при нажатию на которую запускается какой-то запрос на сервер через suspend функцию, и пока запрос идёт кнопка должна быть заблокирована как-то так:
val cs = rememberCoroutineScope()
var buttonEnabled by remember { mutableState(true) }
...
Button(onClick = {
buttonEnabled = false
cs.launch {
myService.callServer();
buttonEnabled = true
}

}, enabled = buttonEnabled )

Если, пока запрос на сервер выполняется, эта композ функция (с кнопкой и скоупом) выйдет из композиции скоуп будет убит и соответственно запрос на сервер будет отменён (по крайней мере частично). Для некоторых ситуаций такое поведение меня не устраивает - т.е. я не хочу чтобы запрос отменялся (особенно если он отменится до посылки на сервер потому что например callServer делает что-то до и это занимает достаточно времени чтобы элемент ушёл из композиции). Для этого я завёл специальный скоуп который живёт на уровне корневой компоуз функции и использую его:
val cs = mySpecialBackgroundScope
// val cs = rememberCoroutineScope()
Непонятно что будет происходить с после myService.callServer();
когда запрос завершится в то время когда функция уже вышла из композиции?

12 ответов

22 просмотра

видимо ничего... отменится саспенд функция и всё

Я бы сделал немного по другому. Я бы сделал чтобы сервис запускал в себе функцию и возвращал бы job. А вы уже делайте job.join и потом включайте кнопку.

Agry-Gami Автор вопроса
Anton Potekhin
Я бы сделал немного по другому. Я бы сделал чтобы ...

Сделал бы что? Чтобы сделать job.join мне в любом случае понадобится скоуп. Чтобы создать job внутри функции сервиса мне тоже нужен какой-то скоуп. Даже если я снаружи буду использовать скоуп из композа а внутри какой-то другой скоуп - это никак не отвечает на мой вопрос... точнее это настолько меняет условия задачи что вопрос теряет смысл :)

а нельзя это всё вынести на уровень вью модели? она работает с suspend функциями и отдаёт нужный стейт наружу через LiveData?

Agry-Gami Автор вопроса
Артём Мельник
а нельзя это всё вынести на уровень вью модели? он...

Да при чём тут это? Ну хорошо, предположим жизненный цикл вью модели привязан к навигации (т.е. уходит экран - убивают вью модель) - тот же самый вопрос, только теперь про вью модели :)

Agry Gami
Да при чём тут это? Ну хорошо, предположим жизненн...

а если умер экран, есть ли смысл думать о кнопках на нём?)

Agry-Gami Автор вопроса
Артём Мельник
а если умер экран, есть ли смысл думать о кнопках ...

Так речь не про кнопки а про взаимодействие с захваченными переменными. Если захвачен не булеан а что-то посложнее и что-то что завязано на компоуз - оно же не сможет отработать.

Agry Gami
Так речь не про кнопки а про взаимодействие с захв...

я не особо силён в компоузе, но кажется, что все запросы должны быть всё же во вью моделе, а из неё торчать наружу стейт и не будет никакого захвата переменных

Agry-Gami Автор вопроса
Артём Мельник
я не особо силён в компоузе, но кажется, что все з...

в моём примере это не "запрос" - т.е. мне не нужны никакие данные от него, это операция что от неё должно торчать из вью модели?

Agry Gami
в моём примере это не "запрос" - т.е. мне не нужны...

так погоди, ты ведь делаешь обращение к myService и, когда он ответит, ты хочешь поменять состояние кнопки, сменить enabled?

Agry Gami
да...

так почему из вью модели на может торчать какой-то стейт а-ля State(val isButtonEnabled: Boolean), который ты обернёшь в LiveData и добавить метод во ViewModel, по типу class SomeViewModel : ViewModel() { private val state: MutableLiveData = ... val state: LiveData = ... fun onSomeButtonClicked() { state.value = state.value!!.copy(isButtonEnabled = false) scope.launch { ..... state.value = state.value!!.copy(isButtonEnabled = true) } }

Похожие вопросы

Обсуждают сегодня

Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
2
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Объясните, пожалуйста, почему компилятор ругается на использование в условии неинициализированной переменной: int x; Task.Run(async () => { x = await somefunc(); }).Wait...
Александр
5
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем привет. Ребята, подскажите, пожалуйста. у ботов есть ограничение на отправку сообщений - 30 сообщений в секунду, эти ограничения накладываются на все сообщения? или на со...
Artem Stormageddon
4
Блин, ребята, сори за тупые вопросы. А можно ли как-то открыть вебапку по нажатию на кнопку в меню(которое появляется слева, команды)?
Artem Stormageddon
3
Коллеги, я тут для личных нужд пошел ставить MQTT сервер, пощупал mosquitto, но ужаснулся отсутствию такой банальности, как HTTP API для посмотреть список топиков. А тут что,...
Maksim Lapshin
14
Карта сайта