2 回答
TA贡献1799条经验 获得超6个赞
首先,switch通道上的那个应该是一个select命令,它的语法略有不同,如下面的示例所示。
其次,尝试以这种方式中断循环的关键问题是for循环是需要中断的东西。您的代码不会这样做 - 程序将到达for i, data := range arr {}块并循环arr直到它到达末尾,之后它将打破case条件。
如果要使用通道来中断for循环,则必须在循环本身中读取通道,如下所示:
func foo(cmd chan string) {
// define arr
// begin loop over arr first
for i, data := range arr {
// check for a command within the loop
select {
case s := <-cmd:
// if cmd contains a value switch on that
switch s {
case "stop":
// do whatever
case "resume":
// do whatever
default:
// handle the case where the command is unrecognized
}
default:
// there is no command, so continue the loop as normal
}
}
return
}
请注意,我不包括“播放”命令。循环的默认行为应该是继续循环,并且检查值“play”的通道意味着必须将其推送到通道以完成此循环的每次迭代。
检查这个操场代码以获得一个简单的例子。
如果要暂停和恢复循环,请将在通道上发送的命令视为有限状态机的转换并采取相应措施:
func foo(cmd chan string) {
state := "play"
for i, data := range arr {
// check for a command within the loop,
// but use different logic if paused to avoid a busyloop
if state == "pause" {
// keep reading cmd until a valid command is received
LOOP:
for s := range cmd {
switch s {
case "stop":
return
case "resume":
state = "play"
break LOOP
default:
// deal with unrecognized command
}
}
// if the channel closes while still in the "pause" state,
// deal with that here
if state == "pause" {
return
}
}
// resume normal operation
select {
case state = <-cmd:
// if cmd contains a value switch on that
switch state {
case "stop":
return
case "pause":
// continue the loop, but pause next time around
default:
// handle the case where the command is unrecognized
}
default:
// there is no command, so continue the loop as normal
}
}
return
}
检查此操场代码以获取此行为的示例。
TA贡献1887条经验 获得超5个赞
解决方案非常简单,因为您需要检查来自客户端的 Stop 信号,启动 goroutine 并侦听客户端 cmd,将 cmd 推送到 cmdCh(例如),然后每次将数据发送到主线程中websocket检查cmd:
for i, data := range arr {
lastIndex = i
select {
case cmd := <-cmdCh:
switch (cmd) {
case "Stop":
return
default:
// send data
}
default:
// send data
}
}
- 2 回答
- 0 关注
- 148 浏览
添加回答
举报
