为何lifecycleScope未等待viewModelScope执行完成就跳转页面?
问题原因
你的代码里,doSomething 是挂起函数,但内部用 viewModelScope.launch 启动了新协程,这个操作是非阻塞的——launch 只会触发协程执行,不会让 doSomething 挂起等待内部任务完成。所以 doSomething 调用后立刻返回,导航代码紧接着就执行了,完全没等内部的长时间任务结束。
解决方法
有两种常用的修正方式,选适合你场景的即可:
方式一:直接在挂起函数内执行任务(推荐)
如果不需要额外启动协程,直接把长时间任务写在 doSomething 里,利用挂起函数本身的特性等待任务完成:
// ViewModel.class suspend fun doSomething() { // 直接执行长时间挂起任务,无需额外 launch delay(10000) // 其他业务逻辑... }
如果必须绑定 viewModelScope(比如需要在ViewModel销毁时取消任务),可以用 async + await 让 doSomething 等待内部任务完成:
// ViewModel.class suspend fun doSomething() { viewModelScope.async { delay(10000) // 其他业务逻辑... }.await() // 等待异步任务完成 }
方式二:返回Job并等待完成
如果一定要保留 viewModelScope.launch,可以让 doSomething 返回这个协程的 Job,在调用处调用 join() 等待任务结束:
// ViewModel.class suspend fun doSomething(): Job { return viewModelScope.launch { delay(10000) // 其他业务逻辑... } } // View.class nextButton.setOnClickListener { val action = FragmentDirections.AToB() lifecycleScope.launch { getViewModel().doSomething().join() // 等待协程任务完成 findNavController().safeNavigate(action) } }
内容的提问来源于stack exchange,提问作者htafoya
相关产品推荐
相关产品推荐

