uniflow-kt / uniflow-kt

Uniflow 🦄 - Simple Unidirectional Data Flow for Android & Kotlin, using Kotlin coroutines and open to functional programming

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect order of state emissions: default state emitted after other state(s)

erikhuizinga opened this issue · comments

AndroidDataFlow.<init> sets the default state asynchronously:

init {
action { setState { defaultState } }
}

However, a common use case for me is to extend AndroidDataFlow and in my implementation's init block I also call action { setState { someStateThatILoaded } }. These two actions are concurrently launched in ActionDispatcher:

fun action(onAction: ActionFunction<UIState>, onError: ActionErrorFunction): ActionFlow = ActionFlow(onAction, onError).also { coroutineScope.launchOnIO { reducer.enqueueAction(it) } }

Remember that CoroutineScope.launch {} returns quickly. However, AFAIK no order of execution is guaranteed! If the scope is backed by multiple threads, the order of these launched jobs is undefined and therefore 🐛 it is undefined which of the two states is set first!

User story

As a user I expect the defaultState constructor argument to be set as soon as all AndroidDataFlow<init> blocks return.

Suggestion

Do not asynchronously set state in AndroidDataFlow.<init>, but instead synchronously set state.

Workaround

Await defaultState and only then start setting your own states. In other words: don't set state from your AndroidDataFlow implementation's init block.

Version affected

UniFlow version: 0.11.2

Fixed in #41

thanks @ggajews