0

バースト書き込みを受信するチャネルがあります。アクションをトリガーする前に、チャネルでの送信のバーストが終了するまで待ちたいと思います。

私はこの要点intervalを見てきましたが、バッファにデータがある場合は毎回出力を送信します:

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
}

私の場合、出力をトリガーまたは送信する前に、このバーストの入力チャネルで送信されるデータがなくなるまで待ちたいと思います。

どうすればこれを達成できますか?

4

2 に答える 2

1

おそらくこの行に沿って、ゴルーチン間の同期が必要なようです。

func main() {

        // Create a channel for our input
        input := make(chan int, 1)
        // Create another for synchronization between main and forked goroutines
        done := make(chan bool)

        go func() {
                // block-wait for received value
                <-input

                // do some more things here

                // when done, send signal to the main goroutine
                done <- true
        }()

        // Do something while wait for the forked goroutine

        // this block until `<-done`
        <-done
        close(mychan)
}

この投稿では、チャネルと同期グループを使用した同期について非常に明確に説明しています。

于 2016-03-14T05:39:19.527 に答える
0

これは、デバウンサーとして実装したものです。

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{}{}
                }
            }
        }
    }()
}

入力で受信しない場合、データのバーストに中断があると想定する期間である休止時間がかかります。1入力1出力の2チャンネルあります。データのバーストが入力に到着し、バーストごとに、バーストの最後に出力チャネルに書き込みます。

実装は非常に単純です。入力チャネルから受信するたびに、現在の UNIX タイムスタンプを保存するだけです。次に、小康状態の時間でティッカーがカチカチ音をたてます。これは、最後のバーストの待機時間を超えたかどうかを確認するだけです。その場合、0 にリセットlastされ、出力チャネルでイベントが発行されます。

入力チャネルでランダムなバーストを送信する 2 秒の静止時間で debounce 関数を使用するコードを次に示します。

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
}
于 2016-03-14T06:38:15.070 に答える