Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type definitions, faster queue, rename pop to shift #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
a simple asynchronous queue

[![Build Status](https://img.shields.io/travis/then/queue/master.svg)](https://travis-ci.org/then/queue)
[![Dependency Status](https://img.shields.io/gemnasium/then/queue.svg)](https://gemnasium.com/then/queue)
[![NPM version](https://img.shields.io/npm/v/then-queue.svg)](http://badge.fury.io/js/then-queue)
[![NPM version](https://img.shields.io/npm/v/then-queue.svg)](https://www.npmjs.com/package/then-queue)

## Installation

Expand All @@ -25,14 +24,10 @@ var q = new Queue();

Push an item onto the queue

### queue.pop() -> Promise Item
### queue.shift() -> Promise Item

Pop an item from the queue
Remove an item from the queue

### queue.length

Amount of items in the queue (note that this can be negative if `pop` has been called more times than `push`).

### Events

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.
Amount of items in the queue (note that this can be negative if `shift` has been called more times than `push`).
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare class ThenQueue<T> {
readonly length: number;
push(item: T | Promise<T>): void;
shift(): Promise<T>
}
export default ThenQueue;
64 changes: 42 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
'use strict';

var EventEmitter = require('events').EventEmitter
var Promise = require('promise')
module.exports = ThenQueue
module.exports.default = ThenQueue

module.exports = Queue
function Queue() {
if (!(this instanceof Queue)) return new Queue()
EventEmitter.call(this)
this._items = []
this._waiting = []
function ThenQueue() {
if (!(this instanceof ThenQueue)) return new ThenQueue()
this._items = new SimpleQueue();
this._waiting = new SimpleQueue();
this.length = 0
}
Queue.prototype = Object.create(EventEmitter.prototype)
Queue.prototype.constructor = Queue

Queue.prototype.push = function(item) {
ThenQueue.prototype.push = function push(item) {
this.length++
this.emit('length-changed', this.length)
if (this._waiting.length) {
var waiting = this._waiting.shift()

var waiting = this._waiting.shift()
if (waiting) {
waiting(item)
}
else {
this._items.push(item)
}
}

Queue.prototype.pop = function(cb) { var self = this
ThenQueue.prototype.shift = function shift() {
this.length--
this.emit('length-changed', this.length)
if (this._items.length) {
var item = this._items.shift()
return Promise.resolve(item).nodeify(cb)

var item = this._items.shift()
if (item) {
return Promise.resolve(item)
}
else {
return new Promise(function(resolve, reject) {
self._waiting.push(resolve)
}).nodeify(cb)
var waiting = this._waiting
return new Promise(function(resolve) {
waiting.push(resolve)
})
}
}

function SimpleQueue() {
this._head = [];
this._tail = [];
}
SimpleQueue.prototype.push = function push(item) {
this._tail.push(item);
}
SimpleQueue.prototype.shift = function shift() {
if (this._head.length !== 0) {
return this._head.pop();
}
if (this._tail.length === 1) {
return this._tail.pop();
}
if (this._tail.length > 1) {
var temp = this._tail.reverse()
this._tail = this._head
this._head = temp
return this._head.pop();
}
return undefined;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
"scripts": {
"test": "node test"
}
}
}
29 changes: 6 additions & 23 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,43 @@ var Queue = require('../')

test('queue', function () {
var q = new Queue();
var length = 0;
var results = [];
q.on('length-changed', function (l) {
assert(q.length === l)
assert(length !== l)
length = l
})
assert(q.length === 0);
q.push(1);
assert(q.length === 1);
assert(length === 1);
q.push(2);
assert(q.length === 2);
assert(length === 2);
q.push(3);
assert(q.length === 3);
assert(length === 3);
return q.pop().then(function (n) {
return q.shift().then(function (n) {
assert(n === 1);
assert(q.length === 2);
assert(length === 2);
return q.pop();
return q.shift();
}).then(function (n) {
assert(n === 2);
assert(q.length === 1);
assert(length === 1);
return q.pop();
return q.shift();
}).then(function (n) {
assert(n === 3);
assert(q.length === 0);
assert(length === 0);
results.push(q.pop());
results.push(q.shift());
assert(q.length === -1);
assert(length === -1);
results.push(q.pop());
results.push(q.shift());
assert(q.length === -2);
assert(length === -2);
results.push(q.pop());
results.push(q.shift());
assert(q.length === -3);
assert(length === -3);
q.push(1);
assert(q.length === -2);
return results.shift();
}).then(function (n) {
assert(n === 1);
q.push(2);
assert(q.length === -1);
assert(length === -1);
return results.shift();
}).then(function (n) {
assert(n === 2);
q.push(3);
assert(q.length === 0);
assert(length === 0);
return results.shift();
}).then(function (n) {
assert(n === 3);
Expand Down