lifecycleScope.launchWhenStarted CoroutineScope 在函数 lambda 中不可用吗?
Isn't lifecycleScope.launchWhenStarted CoroutineScope available in a functions lambda?
我有以下代码片段:
lifecycleScope.launchWhenStarted {
setDiscrepancyChips(basicRegisterItemList = Repository.getTableSet(RegisterType.DISCREPANCY),
chipGroup = fragmentOfflinePhotoCategorySelection.selectionChipsPhotoCategoryDiscrepancyChipGroup,
registrationSetResult = Repository.getRegistrationDiscrepancyIdSet(assignmentId = assignmentId)
){discrepancyId, isChecked ->
Log.i(TAG, "onViewCreated: P103: discrepancyId=$discrepancyId, isChecked = $isChecked")
Repository.updateRegistrationDiscrepancyId(assignmentId = assignmentId, discrepancyId = discrepancyId, isChecked)
}
}
这里我的编译器抱怨 Repository.updateRegistrationDiscrepancyId
不在协程体内...
...这会说 lambda 需要像这样定义它自己的 CoroutineScope 吗?
lifecycleScope.launchWhenStarted {
setDiscrepancyChips(basicRegisterItemList = Repository.getTableSet(RegisterType.DISCREPANCY),
chipGroup = fragmentOfflinePhotoCategorySelection.selectionChipsPhotoCategoryDiscrepancyChipGroup,
registrationSetResult = Repository.getRegistrationDiscrepancyIdSet(assignmentId = assignmentId)
){discrepancyId, isChecked ->
Log.i(TAG, "onViewCreated: P103: discrepancyId=$discrepancyId, isChecked = $isChecked")
lifecycleScope.launchWhenStarted {
Repository.updateRegistrationDiscrepancyId(assignmentId = assignmentId, discrepancyId = discrepancyId, isChecked)
}
}
}
我觉得在彼此内部创建两个 CoroutineScopes 有点尴尬,或者我应该将 lambda 视为一个单独的代码块,它需要创建自己的协程范围。
lambda 本质上就是一个函数,就像 kotlin 中的任何其他函数一样,lambda 可以用 suspend
修饰符标记。
当 lambda 被调用时,它开始像普通的 kotlin 函数一样执行,如果它是一个暂停的 lambda,那么它可以调用其他暂停函数,但如果不是,那么它不能这样做,这就是你面临的问题。
这样想,假设您有以下代码
lifecycleScope.launchWhenStarted{
someFun()
}
private fun someFun(){
Repository.updateRegistrationDiscrepancyId()
// you get the same error as you do now
}
你的 lambda 就像 someFun
,因为它没有挂起,所以不能调用挂起函数。
您已经使用的另一个选项是用 suspend
修饰符标记 setDiscrepancyChips
中的 lambda 参数。如果 setDiscrepancyChips
本身正在挂起,那么 lambda 将开始在 setDiscrepancyChips
的协程范围内执行(仍然取决于它如何调用 lambda),否则它必须启动一个新的协程来调用 lambda
我有以下代码片段:
lifecycleScope.launchWhenStarted {
setDiscrepancyChips(basicRegisterItemList = Repository.getTableSet(RegisterType.DISCREPANCY),
chipGroup = fragmentOfflinePhotoCategorySelection.selectionChipsPhotoCategoryDiscrepancyChipGroup,
registrationSetResult = Repository.getRegistrationDiscrepancyIdSet(assignmentId = assignmentId)
){discrepancyId, isChecked ->
Log.i(TAG, "onViewCreated: P103: discrepancyId=$discrepancyId, isChecked = $isChecked")
Repository.updateRegistrationDiscrepancyId(assignmentId = assignmentId, discrepancyId = discrepancyId, isChecked)
}
}
这里我的编译器抱怨 Repository.updateRegistrationDiscrepancyId
不在协程体内...
...这会说 lambda 需要像这样定义它自己的 CoroutineScope 吗?
lifecycleScope.launchWhenStarted {
setDiscrepancyChips(basicRegisterItemList = Repository.getTableSet(RegisterType.DISCREPANCY),
chipGroup = fragmentOfflinePhotoCategorySelection.selectionChipsPhotoCategoryDiscrepancyChipGroup,
registrationSetResult = Repository.getRegistrationDiscrepancyIdSet(assignmentId = assignmentId)
){discrepancyId, isChecked ->
Log.i(TAG, "onViewCreated: P103: discrepancyId=$discrepancyId, isChecked = $isChecked")
lifecycleScope.launchWhenStarted {
Repository.updateRegistrationDiscrepancyId(assignmentId = assignmentId, discrepancyId = discrepancyId, isChecked)
}
}
}
我觉得在彼此内部创建两个 CoroutineScopes 有点尴尬,或者我应该将 lambda 视为一个单独的代码块,它需要创建自己的协程范围。
lambda 本质上就是一个函数,就像 kotlin 中的任何其他函数一样,lambda 可以用 suspend
修饰符标记。
当 lambda 被调用时,它开始像普通的 kotlin 函数一样执行,如果它是一个暂停的 lambda,那么它可以调用其他暂停函数,但如果不是,那么它不能这样做,这就是你面临的问题。
这样想,假设您有以下代码
lifecycleScope.launchWhenStarted{
someFun()
}
private fun someFun(){
Repository.updateRegistrationDiscrepancyId()
// you get the same error as you do now
}
你的 lambda 就像 someFun
,因为它没有挂起,所以不能调用挂起函数。
您已经使用的另一个选项是用 suspend
修饰符标记 setDiscrepancyChips
中的 lambda 参数。如果 setDiscrepancyChips
本身正在挂起,那么 lambda 将开始在 setDiscrepancyChips
的协程范围内执行(仍然取决于它如何调用 lambda),否则它必须启动一个新的协程来调用 lambda