doupin5408 2016-03-14 05:01
浏览 21
已采纳

如何等待频道活动中的停顿触发某些事件?

I have a channel that will receive bursts of writes to it. I want to wait until a burst of sends on the channel have finished before triggering an action.

I have looked at this gist, however, it will send on the output every intervalif there is data in the buffer:

func debounceChannel(interval time.Duration, output chan int) chan int {
  input := make(chan int)

  go func() {
    var buffer int
    var ok bool

    // We do not start waiting for interval until called at least once
    buffer, ok = <-input 
    // If channel closed exit, we could also close output
    if !ok {
      return
    }

    // We start waiting for an interval
    for {
      select {
      case buffer, ok = <-input:
        // If channel closed exit, we could also close output
        if !ok {
          return
        }

      case <-time.After(interval):
        // Interval has passed and we have data, so send it
        output <- buffer
        // Wait for data again before starting waiting for an interval
        buffer, ok = <-input
        if !ok {
          return
        }
        // If channel is not closed we have more data and start waiting for interval
      }
    }
  }()

  return input
}

In my case, I want to wait until there is no longer any data being sent on the input channel for this burst before triggering or sending on the output.

How do I achieve this?

  • 写回答

2条回答 默认 最新

  • dougang1965 2016-03-14 06:38
    关注

    This is what I ended up implementing as my debouncer:

    func Debounce(lull time.Duration, in chan struct{}, out chan struct{}) {
    
        go func() {
    
            var last int64 = 0
    
            for {
                select {
                case <-in:
                    last = time.Now().Unix()
    
                case <-time.Tick(lull):
                    if last != 0 && time.Now().Unix() >= last+int64(lull.Seconds()) {
                        last = 0
                        out <- struct{}{}
                    }
                }
            }
        }()
    }
    

    It takes a lull time which is the duration where if we do not receive on the input, then we assume there is a break in the bursts of data. There are 2 channels, 1 input and 1 output. The bursts of data arrives on the input, and for each burst, we write to the output channel at the end of the burst.

    The implementation is extremely simplistic. I just store the current unix timestamp every time I receive from the input channel. Then, I have a ticker ticking with a duration of the lull time. All this does is check to see if we've exceeded the wait time for the last burst. If so, it resets last to 0 an emits an event on the output channel.

    Here's some code using the debounce function with a lull time of 2 seconds which sends random bursts on the input channel:

    func main() {
    
        out := make(chan struct{})
        in := make(chan struct{})
    
        Debounce(2*time.Second, in, out)
    
        // Generating bursts of input data
        go func(in chan struct{}) {
    
            for {
                select {
                case <-time.Tick(1 * time.Second):
                    in <- struct{}{}
    
                    fmt.Println("Sending!")
    
                    shouldSleep := rand.Intn(2)
                    if shouldSleep == 1 {
                        time.Sleep(5 * time.Second)
                    }
                }
            }
        }(in)
    
        // Listening for output events
        go func(out chan struct{}) {
    
            for _ = range out {
                fmt.Println("Got an event!")
            }
        }(out)
    
        // Do not let main terminate.
        done := make(chan struct{})
        <-done
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题
  • ¥15 ad5933的I2C
  • ¥15 请问RTX4060的笔记本电脑可以训练yolov5模型吗?
  • ¥15 数学建模求思路及代码
  • ¥50 silvaco GaN HEMT有栅极场板的击穿电压仿真问题