为了账号安全,请及时绑定邮箱和手机立即绑定

暂停和开始循环

暂停和开始循环

Go
慕沐林林 2022-07-11 17:19:54
当客户端连接到服务器时,我正在将他们的连接升级到 websocket 连接并从一个大的 json 文件向他们发送回数据。这工作正常,但是,当用户想要停止时,我收到命令并想要pause数据流,然后当他们想要resume数据时继续发送。我似乎无法使用后两个选项。我看过频道,但似乎无法安静地知道该怎么做。我所拥有的是这样的func foo() {    switch cmd {    case "play":      for _, data := range arr {         // send data      }    case "stop":    case "resume":}我尝试了几件事,但无法真正按照我想要的方式得到它,其中一个是渠道,我似乎无法按照我想要的方式工作,另一个正在break使用标记的循环,由于范围而不起作用:func foo() {    var lastIndex := 0    switch cmd {    case "play":    Loop: // <-- not used      for i, data := range arr {         lastIndex = i         // send data      }    case "stop":      break Loop // <-- error Loop not defined    case "resume":    // start to send the data back from lastIndex}我在上面的正确轨道上吗?渠道是否更好?还是有更好的方法来做到这一点? 这是一个例子
查看完整描述

2 回答

?
哈士奇WWW

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

}

检查此操场代码以获取此行为的示例。


查看完整回答
反对 回复 2022-07-11
?
慕工程0101907

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

     }

 }


查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 148 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号