syncqueue.coffee 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. # A synchronous processing queue. The queue calls process on the arguments,
  2. # ensuring that process() is only executing once at a time.
  3. #
  4. # process(data, callback) _MUST_ eventually call its callback.
  5. #
  6. # Example:
  7. #
  8. # queue = require 'syncqueue'
  9. #
  10. # fn = queue (data, callback) ->
  11. # asyncthing data, ->
  12. # callback(321)
  13. #
  14. # fn(1)
  15. # fn(2)
  16. # fn(3, (result) -> console.log(result))
  17. #
  18. # ^--- async thing will only be running once at any time.
  19. module.exports = (process) ->
  20. throw new Error('process is not a function') unless typeof process == 'function'
  21. queue = []
  22. enqueue = (data, callback) ->
  23. queue.push [data, callback]
  24. flush()
  25. enqueue.busy = false
  26. flush = ->
  27. return if enqueue.busy or queue.length == 0
  28. enqueue.busy = true
  29. [data, callback] = queue.shift()
  30. process data, (result...) -> # TODO: Make this not use varargs - varargs are really slow.
  31. enqueue.busy = false
  32. # This is called after busy = false so a user can check if enqueue.busy is set in the callback.
  33. callback.apply null, result if callback
  34. flush()
  35. enqueue