Skip to content

Instantly share code, notes, and snippets.

@josher19
Created April 20, 2012 09:38
Show Gist options
  • Save josher19/2427357 to your computer and use it in GitHub Desktop.
Save josher19/2427357 to your computer and use it in GitHub Desktop.
Limited Queue based on suggestions from http://stereopsis.com/async/
# On user event -> push event into a n-element queue.
# If the number of outstanding requests is <n, fire request immediately.
# When an outstanding request works or fails, fire a pending queued request if one is waiting.
EventEmitter = process.EventEmitter or require?('events').EventEmitter or {}
LimitedQueue = (@n = 2, @log = false) ->
@log = console.log if @log is true and console? and console.log
@q = []
@req = []
this
LimitedQueue.prototype = new EventEmitter()
# On user event -> push event into a n-element queue.
LimitedQueue::add = (fn) ->
# If the number of outstanding requests is <n, fire request immediately.
if @req.length < @n
@req.push fn
done = @done.bind(this)
# call done when fn finishes
fn(done,done)
@emit?("start", arguments)
else
@q.push fn
this
# When an outstanding request works or fails, fire a pending queued request if one is waiting.
LimitedQueue::done = (err, success) ->
@req.pop()
@emit?("done", @len())
@fire()
LimitedQueue::fire = ->
next = @q.shift()
@add next if next
if @empty()
@log "Queue empty" if @log
@emit?("alldone")
LimitedQueue::empty = ->
return 0 is @len()
# Some IE browsers do not support Function::bind
LimitedQueue::done.bind ?= (obj, args...) ->
return -> LimitedQueue::done.call(obj, args);
LimitedQueue::len = ->
@q.length + @req.length
module.exports = LimitedQueue if module?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment