| 1 | const noOp = () => {} |
| 2 | |
| 3 | export default function smartQueue(handler, opts) { |
| 4 | opts = opts || {} |
| 5 | var timer, tmp, running |
| 6 | var queue = opts.initial || [] |
| 7 | var max = opts.max || Infinity |
| 8 | var int = opts.interval || 10e3 |
| 9 | var onEmpty = opts.onEmpty || noOp |
| 10 | var onPause = opts.onPause || noOp |
| 11 | |
| 12 | function batch(all) { |
| 13 | clearInterval(timer) |
| 14 | var removed = queue.splice(0, max) |
| 15 | /* If queue chunk has no items */ |
| 16 | // if (!removed.length) { |
| 17 | // running = false |
| 18 | // return onEnd(queue, 'process-empty') |
| 19 | // } |
| 20 | if (removed.length) { |
| 21 | handler(removed, queue) |
| 22 | } |
| 23 | /* If queue backlog has no items */ |
| 24 | if (!queue.length) { |
| 25 | running = false |
| 26 | // return onEnd(queue, 'end') |
| 27 | return onEmpty(queue) |
| 28 | } |
| 29 | |
| 30 | if (all) { |
| 31 | return batch() |
| 32 | } |
| 33 | return ticker() |
| 34 | } |
| 35 | |
| 36 | function ticker() { |
| 37 | running = true |
| 38 | timer = setInterval(batch, int) |
| 39 | } |
| 40 | |
| 41 | // Start queue if items |
| 42 | if (queue.length) { |
| 43 | ticker() |
| 44 | } |
| 45 | |
| 46 | return { |
| 47 | flush: function(all) { |
| 48 | batch(all) |
| 49 | }, |
| 50 | resume: batch, |
| 51 | push: function(val) { |
| 52 | tmp = queue.push(val) |
| 53 | /* Clear if overflow */ |
| 54 | if (tmp >= max && !opts.throttle) { |
| 55 | batch() // immediately process overflow in queue |
| 56 | } |
| 57 | if (!running) { |
| 58 | ticker() |
| 59 | } |
| 60 | return tmp |