如何使Coroutines仅在第一次完成后才启动下一份工作
假设我有一个按钮,它在Android中有一个侦听器:
someView.setOnClickListener {
viewModel.doSomething()
}
每次按下按钮时,这都会创建一个新工作。在我的ViewModel中,Dosothing函数正在从ViewModelScope启动暂停函数:
fun doSomething() {
viewModelScope.launch {
doSomething1()
doSomething2()
doSomething3()
}
}
suspend fun doSomething1() {
delay(100)
Log.d("TEST", "doSomething1: 1 ")
}
suspend fun doSomething2() {
delay(300)
Log.d("TEST", "doSomething2: 2 ")
}
fun doSomething3() {
Log.d("TEST", "doSomething3: 3 ")
}
现在,如果此按钮连续地按非常快速按下(从理论上讲,我可以两次从听众中调用该功能,以便执行第一个呼叫尚未完成),我将在我的logcat中得到以下结果:
d/test:Dosomething 1:1 D/测试:Dosomething 1:1 D/测试:Dosomething 2:2 D/测试:Dosomething 3:3 D/测试:Dosomething 2:2 D/测试:Dosomething 3:3
我实际想实现的是,如果我可以从同一范围启动dosomething()
,将会发生什么,因此它运行同步。
d/test:Dosomething 1:1 D/测试:Dosomething 1:2 D/测试:Dosomething 2:3 D/测试:Dosomething 3:1 D/测试:Dosomething 2:2 D/测试:Dosomething 3:3
我该如何实现这种行为,以便在开始同一个Coroutine之前,必须完成第一个行为?
Lets say that I have a button, which has a listener in Android:
someView.setOnClickListener {
viewModel.doSomething()
}
This will create a new Job for each time that the button is pressed. In my ViewModel, the doSomething function is launching suspend functions from the viewModelScope:
fun doSomething() {
viewModelScope.launch {
doSomething1()
doSomething2()
doSomething3()
}
}
suspend fun doSomething1() {
delay(100)
Log.d("TEST", "doSomething1: 1 ")
}
suspend fun doSomething2() {
delay(300)
Log.d("TEST", "doSomething2: 2 ")
}
fun doSomething3() {
Log.d("TEST", "doSomething3: 3 ")
}
Now, if this button gets pressed very quickly in succession (in theory, lets say i can call the function from the listener twice, so that the execution of the first call hasn't finished yet), I will get following result in my logcat:
D/TEST: doSomething1: 1 D/TEST: doSomething1: 1 D/TEST: doSomething2: 2 D/TEST: doSomething3: 3 D/TEST: doSomething2: 2 D/TEST: doSomething3: 3
What I actually want to achieve is, what would happen if I could launch doSomething()
twice from the same scope, so it runs synchronous.
D/TEST: doSomething1: 1 D/TEST: doSomething1: 2 D/TEST: doSomething2: 3 D/TEST: doSomething3: 1 D/TEST: doSomething2: 2 D/TEST: doSomething3: 3
How can I achieve that behaviour, so that before starting the same coroutine, the first one has to finish?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用MUTEX锁来执行此操作 - 无论您按下多少次按钮,锁定锁定序列都无法启动直到完成。
您也可以使用频道一次运行一个频道
You can use a Mutex lock to do this - the lock would keep subsequent 1-2-3 sequences from launching until the prior ones are complete, no matter how many times you push the button.
You could also use a channel to run them one at a time
可以通过保存最后一份工作并等待完成新的Coroutine来解决:
Can be solved by saving the last job and waiting for it to finish before executing a new coroutine: