a-promise-queue
Advanced tools
Comparing version 1.1.0 to 2.0.0
39
index.js
class PromiseQueue { | ||
constructor (cb, concurrency, PromiseFlavour) { | ||
const flavour = (typeof concurrency !== 'number') ? concurrency : PromiseFlavour | ||
constructor (options, callback) { | ||
const cb = (typeof options === 'function') ? options : callback | ||
const opts = (options && typeof options === 'object') ? options : {} | ||
this.flushing = false | ||
this.Promise = flavour || Promise | ||
this.concurrency = (typeof concurrency !== 'number') ? 1 : concurrency | ||
this.Promise = opts.promise || Promise | ||
this.concurrency = (!opts.concurrency || typeof opts.concurrency !== 'number') ? 1 : opts.concurrency | ||
this.promises = [] | ||
this.queue = [] | ||
this.callback = cb | ||
if (!cb) { | ||
this._makePromise() | ||
} | ||
} | ||
_makePromise () { | ||
this._finalPromise = new Promise((resolve, reject) => { | ||
this.resolve = resolve | ||
this.reject = reject | ||
}) | ||
} | ||
then (onResolve, onReject) { | ||
if (this.callback) throw new Error('Cannot use PromiseQueue as a Promise if callback has been is set') | ||
return this._finalPromise.then(onResolve, onReject) | ||
} | ||
catch (onReject) { | ||
if (this.callback) throw new Error('Cannot use PromiseQueue as a Promise if callback has been is set') | ||
return this._finalPromise.catch(onReject) | ||
} | ||
add (fn, opts) { | ||
@@ -93,3 +114,3 @@ if (typeof fn !== 'function') throw new Error('PromiseQueue.add() expects a function as an argument.') | ||
this.promises.splice(promiseId, 1) | ||
if (this.promises.length === 0 && typeof this.callback === 'function') this.callback() | ||
if (this.promises.length === 0) this._done() | ||
return true | ||
@@ -111,4 +132,12 @@ } | ||
} | ||
_done (err) { | ||
if (typeof this.callback === 'function') this.callback(err) | ||
else if (this._finalPromise) { | ||
this.resolve() | ||
this._makePromise() | ||
} | ||
} | ||
} | ||
module.exports = PromiseQueue |
{ | ||
"name": "a-promise-queue", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "A native es6 promise queue with optional retry attempts.", | ||
@@ -8,2 +8,3 @@ "main": "index.js", | ||
"test": "tape test.js", | ||
"lint": "standard", | ||
"test-pretty": "tape test.js | faucet", | ||
@@ -10,0 +11,0 @@ "test-travis": "nyc tape test.js | tap-spec", |
@@ -16,3 +16,3 @@ # a promise queue | ||
``` | ||
npm install a-promise-queue | ||
npm install a-promise-queue --save | ||
``` | ||
@@ -22,9 +22,15 @@ | ||
+ `queue = new PromiseQueue([Function callback], [Promise flavour])` | ||
`queue = new PromiseQueue([Function callback], [Number concurrency], [Promise flavour])` | ||
Callback is fired whenever queue is emptied. | ||
Optional flavour lets you set the type of promises used, defaults to es6 native promises. | ||
Optional concurrency lets you set the number of promises to run in parallel. | ||
+ `queue = new PromiseQueue([options], [Function callback])` | ||
Callback is fired whenever queue is emptied. If callback is not provided, queue will act as a promise which is resolved once queue is finished. | ||
Options: | ||
``` | ||
{ | ||
promise: Promise, // the type of promises used. defaults to es6 native promises, | ||
concurrency: Number // set the number of promises to run in parallel. | ||
} | ||
``` | ||
+ `queue.length` | ||
Returns number of promises waiting to be executed. | ||
+ `var promise = queue.add(Function generator, [Object options])` | ||
@@ -39,2 +45,3 @@ Returns a promise which is resolved or rejected when the promise produced by the generator is eventually resolved. | ||
``` | ||
+ `var promise = queue.flush()` | ||
@@ -41,0 +48,0 @@ Runs all promises currently in the queue concurrently. |
127
test.js
@@ -1,2 +0,2 @@ | ||
const Promise = require('bluebird') | ||
const BlueBirdPromise = require('bluebird') | ||
const tape = require('tape') | ||
@@ -14,5 +14,5 @@ const PromiseQueue = require('./index.js') | ||
const queue = new PromiseQueue(() => t.end()) | ||
queue.add(() => Promise.delay(100).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(100).then(count)) | ||
queue.add(expectOrder(1)) | ||
queue.add(() => Promise.delay(10).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count)) | ||
queue.add(expectOrder(2)) | ||
@@ -31,4 +31,4 @@ }) | ||
const queue = new PromiseQueue(() => t.end()) | ||
queue.add(() => Promise.delay(10).then(count)).then(expectReturnedValue(1)).catch(fail(t)) | ||
queue.add(() => Promise.delay(10).then(count)).then(expectReturnedValue(2)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count)).then(expectReturnedValue(1)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count)).then(expectReturnedValue(2)).catch(fail(t)) | ||
}) | ||
@@ -43,8 +43,8 @@ | ||
const queue = new PromiseQueue(() => t.end()) | ||
queue.add(() => Promise.delay(10).then(count), { priority: 0 }).then(expectOrder(1)).catch(fail(t)) | ||
queue.add(() => Promise.delay(10).then(count), { priority: 0 }).then(expectOrder(5)).catch(fail(t)) | ||
queue.add(() => Promise.delay(10).then(count), { priority: 2 }).then(expectOrder(3)).catch(fail(t)) | ||
queue.add(() => Promise.delay(10).then(count), { priority: 0 }).then(expectOrder(6)).catch(fail(t)) | ||
queue.add(() => Promise.delay(10).then(count), { priority: 2 }).then(expectOrder(4)).catch(fail(t)) | ||
queue.add(() => Promise.delay(10).then(count), { priority: 5 }).then(expectOrder(2)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count), { priority: 0 }).then(expectOrder(1)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count), { priority: 0 }).then(expectOrder(5)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count), { priority: 2 }).then(expectOrder(3)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count), { priority: 0 }).then(expectOrder(6)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count), { priority: 2 }).then(expectOrder(4)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count), { priority: 5 }).then(expectOrder(2)).catch(fail(t)) | ||
}) | ||
@@ -62,3 +62,3 @@ | ||
queue.add(() => Promise.reject(new Error('test'))).catch(countCatches) | ||
queue.add(() => Promise.delay(10).then(count)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(10).then(count)).catch(fail(t)) | ||
queue.add(() => Promise.reject(new Error('test'))).catch(countCatches) | ||
@@ -80,3 +80,3 @@ queue.add(() => Promise.reject(new Error('test'))).catch(countCatches) | ||
const queue = new PromiseQueue() | ||
queue.add(() => Promise.delay(20)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(20)).catch(fail(t)) | ||
queue.add(failing, { attempts: 3 }).catch(fail(t)) | ||
@@ -108,6 +108,6 @@ queue.add(() => { | ||
const count = () => { counter += 1 } | ||
queue.add(() => Promise.delay(20).then(count)) | ||
queue.add(() => Promise.delay(20).then(count)) | ||
queue.add(() => Promise.delay(20).then(count)) | ||
queue.add(() => Promise.delay(20).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(20).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(20).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(20).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(20).then(count)) | ||
queue.flush().then(() => { | ||
@@ -117,3 +117,3 @@ flushed = true | ||
}) | ||
queue.add(() => Promise.delay(20).then(count)) | ||
queue.add(() => BlueBirdPromise.delay(20).then(count)) | ||
.then(() => { | ||
@@ -138,7 +138,7 @@ t.same(counter, 5) | ||
const queue = new PromiseQueue(finished) | ||
queue.add(() => Promise.delay(20).then(count)).catch(fail(t)) | ||
queue.add(() => BlueBirdPromise.delay(20).then(count)).catch(fail(t)) | ||
queue.add(expectOrder(1)).catch(fail(t)) | ||
Promise.delay(40).then(() => { | ||
queue.add(() => Promise.delay(10).then(count)).catch(fail(t)) | ||
BlueBirdPromise.delay(40).then(() => { | ||
queue.add(() => BlueBirdPromise.delay(10).then(count)).catch(fail(t)) | ||
queue.add(expectOrder(2)).catch(fail(t)) | ||
@@ -154,11 +154,90 @@ }) | ||
const queue = new PromiseQueue(finished, 5) | ||
const queue = new PromiseQueue({ concurrency: 5 }, finished) | ||
for (i = 0; i < 5; i++) { | ||
queue.add(() => Promise.delay(20)) | ||
queue.add(() => BlueBirdPromise.delay(20)) | ||
} | ||
t.same(queue.length, 0) | ||
for (i = 0; i < 5; i++) { | ||
queue.add(() => Promise.delay(20)) | ||
queue.add(() => BlueBirdPromise.delay(20)) | ||
} | ||
t.same(queue.length, 5) | ||
}) | ||
tape('can be configured with custom promises', (t) => { | ||
const queue = new PromiseQueue({ promise: BlueBirdPromise }) | ||
t.same(queue.Promise, BlueBirdPromise) | ||
t.end() | ||
}) | ||
tape('uses native promises by default', (t) => { | ||
const queue = new PromiseQueue() | ||
t.same(queue.Promise, Promise) | ||
t.end() | ||
}) | ||
tape('promise queue can be returned as if it is a promise', (t) => { | ||
let count = 0 | ||
const queue = new PromiseQueue() | ||
for (let i = 0; i < 5; i++) { | ||
queue.add(() => BlueBirdPromise.delay(5).then(() => count++)) | ||
} | ||
queue.then(() => { | ||
t.same(count, 5) | ||
t.same(queue.length, 0) | ||
t.end() | ||
}) | ||
}) | ||
tape('promise queue is reuseable as a promise', (t) => { | ||
let count = 0 | ||
const queue = new PromiseQueue() | ||
for (let i = 0; i < 5; i++) { | ||
queue.add(() => BlueBirdPromise.delay(5).then(() => count++)) | ||
} | ||
queue.then(() => { | ||
t.same(count, 5) | ||
t.same(queue.length, 0) | ||
for (let i = 0; i < 5; i++) { | ||
queue.add(() => BlueBirdPromise.delay(5).then(() => count++)) | ||
} | ||
return queue | ||
}) | ||
.then(() => { | ||
t.same(count, 10) | ||
t.same(queue.length, 0) | ||
t.end() | ||
}) | ||
}) | ||
tape('if promise queue has callback it cannot be used as promise', (t) => { | ||
const finished = () => {} | ||
const queue = new PromiseQueue(finished) | ||
t.throws(() => queue.then(), /Cannot use PromiseQueue as a Promise if callback has been is set/) | ||
t.throws(() => queue.catch(), /Cannot use PromiseQueue as a Promise if callback has been is set/) | ||
t.end() | ||
}) | ||
tape('throws error if queue.add() is not passed a function', (t) => { | ||
const finished = () => {} | ||
const queue = new PromiseQueue(finished) | ||
t.throws(() => queue.add(), /PromiseQueue.add\(\) expects a function as an argument/) | ||
t.end() | ||
}) | ||
tape('queue.add() handles non promise returning functions', (t) => { | ||
const finished = () => { t.end() } | ||
const queue = new PromiseQueue(finished) | ||
queue.add(() => 1).then(res => t.same(res, 1)) | ||
}) | ||
tape('queue.add() handles non promise returning functions that throw', (t) => { | ||
const queue = new PromiseQueue() | ||
queue.add(() => { throw new Error('failed') }) | ||
.then( | ||
() => t.fail('should have actually thrown error'), | ||
(e) => { | ||
t.same(e.message, 'failed') | ||
t.end() | ||
} | ||
) | ||
}) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
14698
333
62
0
7