Kotlin协程正确的调度器使用

huangapple go评论65阅读模式
英文:

Kotlin Coroutines Correct Dispatcher Usage

问题

以下是您提供的代码的翻译部分:

你认为以下的 Dispatcher 使用是否正确没有任何特定 Dispatcher 的 launch 和具有特定 Dispatcher 的 launch 有什么区别

var loading by mutableStateOf(false)

var errorMsg by mutableStateOf("")

private fun setLoading(isLoading: Boolean) {
    loading = isLoading
}

fun signUp() {
    viewModelScope.launch(Dispatchers.IO) {
        signUpFirebaseUseCase.invoke(email, password).collect { result ->
            withContext(Dispatchers.Main) {
                when (result) {
                    is Response.Success -> {
                        setLoading(isLoading = false)
                    }
                    is Response.Loading -> {
                        setLoading(isLoading = true)
                    }
                    is Response.Error -> {
                        errorMsg = result.errorMessage
                        setLoading(isLoading = false)
                    }
                }
            }
        }
    }
}

请注意,我已将HTML实体代码(如">)替换为相应的字符。如果您有任何进一步的问题或需要其他翻译,请随时提出。

英文:

Do you think the following Dispatcher usage is correct? What is the difference launch without any specific dispatcher and launch with specific dispatcher?

var loading by mutableStateOf(false)

var errorMsg by mutableStateOf("")

private fun setLoading(isLoading: Boolean) {
    loading  = isLoading
}

fun signUp() {
  viewModelScope.launch(Dispatchers.IO) {
        signUpFirebaseUseCase.invoke(email, password).collect { result ->
            withContext(Dispatchers.Main) {
                when (result) {
                    is Response.Success -> {
                        setLoading(isLoading = false)
                    }
                    is Response.Loading -> {
                        setLoading(isLoading = true)
                    }
                    is Response.Error -> {
                        errorMsg = result.errorMessage
                        setLoading(isLoading = false)
                    }
                }
            }
        }
    }
} 

答案1

得分: 2

使用Dispatchers.IO启动会导致signUpFirebaseUseCase.invoke在IO线程上调用,这是没有意义的,因为我假设它不是一个阻塞的函数。它只是生成一个Flow,所以不应该是阻塞的或暂停的。

如果你不在Dispatchers.IO上启动,那么你可以使用Dispatchers.Main.immediate启动,默认情况下viewModelScope也是这样,所以你可以删除collect中的withContext包装。

简短的答案是,如果signUpFirebaseUseCase.invoke()正确地不会阻塞,你不需要在这段代码中提到任何调度器。

为了使代码更具可读性,我推荐使用onEach/launchIn模式。它减少了代码的嵌套。

英文:

Launching with Dispatchers.IO causes signUpFirebaseUseCase.invoke to be called on an IO thread, which is pointless since I assume it is not a blocking function. All it's doing is generating a Flow, so it shouldn't be blocking or suspending.

If you don't launch on Dispatchers.IO, then you're launching with Dispatchers.Main.immediate, the default for viewModelScope, so you could remove the withContext wrapper inside your collect.

The short answer is, if signUpFirebaseUseCase.invoke() correctly does not block, you do not need to mention any dispatchers anywhere in this code.

For more readable code, I recommend the onEach/launchIn pattern. It reduces nesting of code.

答案2

得分: 0

如果您在启动时未传递dispatcherlaunch,它将默认使用在启动该launchCoroutineScope上下文中存在的dispatcher。如果协程上下文没有dispatcher,那么launch将使用Dispatchers.Default

参考链接:Co-routines Launch

英文:

If you don't pass a dispatcher to launch, it will default to the dispatcher present in the context of the CoroutineScope in which you started that launch. If the coroutine context doesn't have a dispatcher, then launch will use Dispatchers.Default.

Reference: Co-routines Launch

huangapple
  • 本文由 发表于 2023年3月31日 21:54:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定