├── .gitignore ├── .jshintrc ├── .travis.yml ├── README.md ├── index.js ├── package.json └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi": true, 3 | "laxbreak": true, 4 | "laxcomma": true, 5 | "node": true, 6 | "strict": true 7 | } 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # then-queue 2 | 3 | a simple asynchronous queue 4 | 5 | [![Build Status](https://img.shields.io/travis/then/queue/master.svg)](https://travis-ci.org/then/queue) 6 | [![Dependency Status](https://img.shields.io/gemnasium/then/queue.svg)](https://gemnasium.com/then/queue) 7 | [![NPM version](https://img.shields.io/npm/v/then-queue.svg)](http://badge.fury.io/js/then-queue) 8 | 9 | ## Installation 10 | 11 | npm install then-queue 12 | 13 | ## API 14 | 15 | ### new Queue() 16 | 17 | ```js 18 | var Queue = require('then-queue'); 19 | var q = new Queue(); 20 | ``` 21 | 22 | A fresh queue! 23 | 24 | ### queue.push(item) 25 | 26 | Push an item onto the queue 27 | 28 | ### queue.pop() -> Promise Item 29 | 30 | Pop an item from the queue 31 | 32 | ### queue.length 33 | 34 | Amount of items in the queue (note that this can be negative if `pop` has been called more times than `push`). 35 | 36 | ### Events 37 | 38 | The `length-changed` event gets emitted whenever `pop` or `push` has been called. You could use it to spawn/kill workers when the length changes. -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var EventEmitter = require('events').EventEmitter 4 | var Promise = require('promise') 5 | 6 | module.exports = Queue 7 | function Queue() { 8 | if (!(this instanceof Queue)) return new Queue() 9 | EventEmitter.call(this) 10 | this._items = [] 11 | this._waiting = [] 12 | this.length = 0 13 | } 14 | Queue.prototype = Object.create(EventEmitter.prototype) 15 | Queue.prototype.constructor = Queue 16 | 17 | Queue.prototype.push = function(item) { 18 | this.length++ 19 | this.emit('length-changed', this.length) 20 | if (this._waiting.length) { 21 | var waiting = this._waiting.shift() 22 | waiting(item) 23 | } 24 | else { 25 | this._items.push(item) 26 | } 27 | } 28 | 29 | Queue.prototype.pop = function(cb) { var self = this 30 | this.length-- 31 | this.emit('length-changed', this.length) 32 | if (this._items.length) { 33 | var item = this._items.shift() 34 | return Promise.resolve(item).nodeify(cb) 35 | } 36 | else { 37 | return new Promise(function(resolve, reject) { 38 | self._waiting.push(resolve) 39 | }).nodeify(cb) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "then-queue", 3 | "version": "1.3.0", 4 | "description": "a simple asynchronous queue", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/then/queue.git" 9 | }, 10 | "keywords": [ 11 | "queue", 12 | "async", 13 | "promise" 14 | ], 15 | "author": "Nathan Zadoks", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/then/queue/issues" 19 | }, 20 | "homepage": "https://github.com/then/queue", 21 | "dependencies": { 22 | "promise": "^6.0.0" 23 | }, 24 | "devDependencies": { 25 | "testit": "~1.2.0" 26 | }, 27 | "scripts": { 28 | "test": "node test" 29 | } 30 | } -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert') 4 | var test = require('testit') 5 | var Queue = require('../') 6 | 7 | test('queue', function () { 8 | var q = new Queue(); 9 | var length = 0; 10 | var results = []; 11 | q.on('length-changed', function (l) { 12 | assert(q.length === l) 13 | assert(length !== l) 14 | length = l 15 | }) 16 | assert(q.length === 0); 17 | q.push(1); 18 | assert(q.length === 1); 19 | assert(length === 1); 20 | q.push(2); 21 | assert(q.length === 2); 22 | assert(length === 2); 23 | q.push(3); 24 | assert(q.length === 3); 25 | assert(length === 3); 26 | return q.pop().then(function (n) { 27 | assert(n === 1); 28 | assert(q.length === 2); 29 | assert(length === 2); 30 | return q.pop(); 31 | }).then(function (n) { 32 | assert(n === 2); 33 | assert(q.length === 1); 34 | assert(length === 1); 35 | return q.pop(); 36 | }).then(function (n) { 37 | assert(n === 3); 38 | assert(q.length === 0); 39 | assert(length === 0); 40 | results.push(q.pop()); 41 | assert(q.length === -1); 42 | assert(length === -1); 43 | results.push(q.pop()); 44 | assert(q.length === -2); 45 | assert(length === -2); 46 | results.push(q.pop()); 47 | assert(q.length === -3); 48 | assert(length === -3); 49 | q.push(1); 50 | assert(q.length === -2); 51 | return results.shift(); 52 | }).then(function (n) { 53 | assert(n === 1); 54 | q.push(2); 55 | assert(q.length === -1); 56 | assert(length === -1); 57 | return results.shift(); 58 | }).then(function (n) { 59 | assert(n === 2); 60 | q.push(3); 61 | assert(q.length === 0); 62 | assert(length === 0); 63 | return results.shift(); 64 | }).then(function (n) { 65 | assert(n === 3); 66 | }); 67 | }); --------------------------------------------------------------------------------