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

循环倒计时

循环倒计时

Go
慕姐4208626 2021-12-27 10:35:43
我目前有这段代码试图计算触发某个条件所用的时间。(伪):timeDelay = 900000 // time.Microsecondfor {   // if a certain something happens, start a counting (time)   if (certainSomething) {      startTime = time.Now();      if !prevTime.IsZero() {        // add the time elapsed time to timeTick        diffTime = time.Since(prevTime)        timeTick = timeTick + diffTime      }      prevTime = startTime   }   if (timeTick < timeDelay) { // lessThan()      // still has not reached target count (time elapsed)      fmt.Println("Not Yet")      // we dont want to get to the end of the loop yet      continue   }   if (timeTick > timeDelay) { // greaterThan()      // has finally reached the target count (time elapsed)      fmt.Println("Yes! Finally")      // yes the delay has been reached lets reset the time      // and if `thisHappened` is triggered again, lets start counting again      timeTick = time.Duration(0 * time.Microsecond)   }   // function shouldn't be called if the elapsed amount   //      of time required has not yet been reached   iShouldOnlyBeCalledWhenDelayHasBeenReached();}我也使用这些作为辅助函数(实际代码)func lessThan(diff time.Duration, upper int) bool {    return diff < time.Duration(upper)*time.Microsecond && diff != 0}func greaterThan(diff time.Duration, upper int) bool {    return diff > time.Duration(upper)*time.Microsecond}但是,我只是对自己的做法感到不舒服。我不应该数数吧?我应该倒计时......我只是很困惑,需要关于我应该使用什么方法的帮助。我想要发生的事情:1.发生timeDelay时从0 开始倒计时certainSomething。2.iShouldOnlyBeCalledWhenDelayHasBeenReached在倒计时达到 0 之前不要调用。 3. 这应该都发生在一个循环内,准确地说是服务器循环接收数据包。我的问题:1. 我应该怎么做才能实现倒计时风格?谢谢,任何建议或示例代码都会有很大帮助。注意:循环中还有其他函数。做其他事情。这是主循环。我来不及了Sleep。
查看完整描述

3 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

您可以设置一个频道,让您知道何时超过了时间。


这是播放示例


它有一个额外的好处,即在 select 语句中,您可以将其他通道用于其他目的。例如,如果您正在此循环中执行其他工作,您还可以在 goroutine 中生成该工作并将结果发送回另一个通道。

然后您timeDelay在其他工作完成之后或其他工作完成时退出,或者其他任何事情。


package main


import (

    "fmt"

    "time"

)


func main() {

    certainSomething := true // will cause time loop to repeat


    timeDelay := 900 * time.Millisecond // == 900000 * time.Microsecond


    var endTime <-chan time.Time // signal for when timer us up


    for {

        // if a certain something happens, start a timer

        if certainSomething && endTime == nil {

            endTime = time.After(timeDelay)

        }

        select {

        case <-endTime:

            fmt.Println("Yes Finally!")

            endTime = nil

        default:

            fmt.Println("not yet")

            time.Sleep(50 * time.Millisecond) // simulate work

            continue

        }


        // function shouldn't be called if the elapsed amount

        //      of time required has not yet been reached

        iShouldOnlyBeCalledWhenDelayHasBeenReached() // this could also just be moved to the <- endtime block above

    }

}


func iShouldOnlyBeCalledWhenDelayHasBeenReached() {

    fmt.Println("I've been called")

}


查看完整回答
反对 回复 2021-12-27
?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

由于这是您所说的游戏,因此在我看来您:


想做X量的工作

如果工作时间超过delay数量,停止工作并再次循环

如果是这种情况,那么您有一些选择和模式。


时间。想到之后。


我喜欢time.Afterselect 语句中的简洁。不需要通道或 goroutine 来处理它。


这种模式还有一个额外的好处,那就是在你的主要游戏逻辑中使用 goroutines。


在玩:http : //play.golang.org/p/FIiUJ0CHZz


更改time.After()以查看它的实际效果。


func main() {


    for {


        // creating a new channel on each loop will allow the

        // GC to collect any game stuff that completes after the timeout.

        done := make(chan int)


        // main game func, doing your other stuff.

        // since this is in a goroutine, it won't block

        // and we can check the state in the select.

        go func(){


            // complicated logic here!

            //


            // you must issue an "I am done!"

            done <- 1

        }()


        // this will block the for loop until a timeout occurs

        select {

            case <- done:

                continue

            case <- time.After(1000 * time.Nanosecond):

                iShouldOnlyBeCalledWhenDelayHasBeenReached()

        }

    }

}


查看完整回答
反对 回复 2021-12-27
?
白衣非少年

TA贡献1155条经验 获得超0个赞

如果你不能让常规睡眠,你应该使用time.Time.Add和time.Time.After(或time.Time.Before)函数。


沿着这些路线的东西


package main         


import "time"        


func main() {        


    var d = 1000 * time.Microsecond

    var t = time.Now().Add(d)


    for {            

        if time.Now().Before(t) {

            continue 

        }            


        do_something()

    }                

}

或者驱逐您必须在可以睡眠的例程中运行一段时间后的方法:


package main         


import "time"        


func main() {


    var d = 1000 * time.Microsecond


    go func() {

        time.Sleep(d)

        do_something()

    }()

}


查看完整回答
反对 回复 2021-12-27
  • 3 回答
  • 0 关注
  • 385 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信