暂停和开始循环

当客户端连接到服务器时,我正在将他们的连接升级到 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

}

我在上面的正确轨道上吗?渠道是否更好?还是有更好的方法来做到这一点? 这是一个例子


慕沐林林
浏览 149回答 2
2回答

哈士奇WWW

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

慕工程0101907

解决方案非常简单,因为您需要检查来自客户端的 Stop 信号,启动 goroutine 并侦听客户端 cmd,将 cmd 推送到 cmdCh(例如),然后每次将数据发送到主线程中websocket检查cmd:for i, data := range arr {&nbsp; &nbsp; &nbsp;lastIndex = i&nbsp; &nbsp; &nbsp;select {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;case cmd := <-cmdCh:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (cmd) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Stop":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // send data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// send data&nbsp; &nbsp; &nbsp;}&nbsp;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go