0

放送オーバーレイ用の一種の「通知システム」を構築しようとしています。基本的に、イベントをキャッチして配列に追加し、その配列を監視する関数を実行します。イベントが追加されるたびに、一定時間かかるアニメーションを実行し、それを配列から削除してから、次のアニメーションに移動します。

それdebounceが私をそこへの道のりの一部にすることがわかりました。アニメーションの実行中に任意の数のイベントを追加でき、キューを空にすることができます。

問題は、最初のイベントが処理される前に、指定された時間 (この場合は 5 秒) 待たなければならないことです。ただし、デバウンスを即時に設定すると、最初のイベントがすぐに処理されるという点ですべてが壊れますが、それ以外は処理されません。

# Pool handling.
pool: []

# Function adds events to the pool array.
addEventToPool: (event, data) ->
  console.log "added #{event} with #{data} to pool!"
  @get('pool').pushObject(data)

# Function that observes the pool array and runs debounce 
# if there are any items in the pool.
observePool: (->
  Ember.run.debounce(@, @handleEvent, 5000, false) if @get('pool').length
).observes('pool.[]')

# Event handling.
handleEvent: ->
  pool = @get('pool')
  object = pool.get('firstObject')
  @set('payload', object)

  Ember.$(".event-message__#{object.event}").addClass('active')

  Ember.run.later (->
    Ember.$(".event-message__#{object.event}").removeClass('active')
    pool.removeObject(object)
  ), 2000

  console.log "Number of remaining objects: #{pool.length}."
  console.log "Objects remaining: #{JSON.stringify pool}."

これを修正するために移動する必要があると感じていますが、debounceその解決策が何であるかはわかりません。

説明が必要な場合はお知らせください。

4

1 に答える 1

3

Ember.run.debounce

の目的は、最後の で呼び出されていないEmber.run.debounce場合に、何かを 1 回だけ実行することです。debounceX seconds

主な用途は、ユーザーが入力を終えた後に何らかのアクションを開始することなどです。そのため、誰かが入力しているすべての文字で呼び出すことができEmber.run.debounce(handleInput, 1000)、キーを何回押しても、関数は一度実行 - 1秒間キーを押さなかった後。

スクロール イベントの処理にも役立ちます。たとえば、ページをスクロールするときに何百ものスクロール イベントが発生しますが、スクロールが停止したときにのみ何らかのアクションを実行したい場合、debounce何百回呼び出しても停止するまで実行されません。値の呼び出し(debounceたとえばtimeout、この場合、最後のスクロール イベントの 100 ミリ秒後)。

これは、あなたがやろうとしていることとは少し違うようです。

推奨される解決策

あなたがやりたいことは、Ember.run.later を使用することだと思います。pool.firstObject を監視するだけの 1 つの関数にすべてを組み合わせることができます。これは、常に最初のオブジェクトをプルし、完了したらそれを削除するためです。

handleEvent: Ember.observer('pool.firstObject', function() {
  var pool = this.get('pool');
  var obj = pool.get('firstObject');
  if (obj) {
    // add class
    Ember.$(".event-message__#{object.event}").addClass('active');

    // schedule remove class for 2 seconds from now
    Ember.run.later(function() {
      Ember.$(".event-message__#{object.event}").removeClass('active');
    }, 2000);

    // schedule remove object from pool 5 seconds from now
    Ember.run.later(function() {
      pool.removeObject(obj);
      // after you've removed this object (which was firstObject)
      // pool.firstObject will change, and the handleEvent function 
      // will get kicked off again
    }, 5000);

  }
})
于 2015-04-22T23:30:55.343 に答える