Comparing version 1.0.5 to 1.1.0
110
enQue.js
@@ -16,2 +16,15 @@ // enQue class | ||
// **Compact** Removes undefined and null values. | ||
// This method should absalutely never be called | ||
// directly, and it will probably become private | ||
// in the future.. but who knows. `que.compact()` | ||
enQue.prototype.compact = function() { | ||
var i = 0; | ||
const res = []; | ||
for (let val of this.que) if(val) res[i++] = val; | ||
this.que = res; | ||
// __returns itself for use in chaining__ | ||
return this; | ||
} | ||
// **enQue.fill** Fills an enQue object with `fn` `n` times. | ||
@@ -34,4 +47,6 @@ // `que.fill((_,n)=>{console.log('works');n()}, 7)` | ||
for(let i = 0, l = fn.length; i < l; i++) { | ||
this.que.push(fn[i]) | ||
this.que.push(fn[i]); | ||
} | ||
} else { | ||
this.que.push(fn); | ||
} | ||
@@ -44,3 +59,4 @@ // __returns itself for use in chaining__ | ||
// `que.clear()` | ||
enQue.prototype.clear = function(fn) { | ||
enQue.prototype.clear = function() { | ||
this.que = []; | ||
return this; | ||
@@ -52,12 +68,30 @@ // __returns itself for use in chaining__ | ||
// `que.remove("(_,n,__,i)=>{console.log(i)}")` | ||
// `que.remove(fn1, 2)` or `que.remove(7)` | ||
// `item` can be a `String`, `Function ref`, or `Number`. | ||
// `amount` is the amount of found `item`'s to remove | ||
// if its not specified **all** `item`s found are removed. | ||
// `que.remove(fn1, 2)` removes 2 occurances of fn1 | ||
// `que.remove(7)` removes the 8th function (0 indexed) | ||
// to remove an array of function refs and/or strinfified functions. | ||
// `que.remove([fn1, "(_,n,__,i)=>{console.log(i)}", fn2])` | ||
// `que.remove([fn1, fn2, fn3], 2)` will only remove fn1 and fn2. | ||
enQue.prototype.remove = function(item, amount) { | ||
// Here we extract the items type. | ||
type = item.constructor.name; | ||
let type = item.constructor.name; | ||
if(type === 'Number') { | ||
return this.que.splice(item, 1); | ||
} | ||
else if(type === "Array") { | ||
amount = amount || Infinity; | ||
let removed = 0; | ||
for(let i=0, l=item.length; i<l; i++) { | ||
var check = item[i].constructor.name === 'Function' ? item[i] : item[i].toString(); | ||
for(let j=0, l2=this.que.length; j<l2; j++) { | ||
// Make sure we dont remove more than amount! | ||
if(removed === amount) break; | ||
if(this.que[j] === check) { | ||
delete this.que[j]; | ||
removed++; | ||
} | ||
} | ||
} | ||
// __returns itself after compacting for use in chaining__ | ||
return this.compact(); | ||
} | ||
else { | ||
@@ -67,12 +101,12 @@ let check = type === 'Function' ? item : item.toString(); | ||
let removed = 0; | ||
for(i=0; i<this.que.length; i++) { | ||
for(let i=0, l=this.que.length; i<l; i++) { | ||
// Make sure we dont remove more than amount! | ||
if(removed === amount) break; | ||
if(check === item) { | ||
this.que.splice(i, 1); | ||
if(check === check.constructor.name === 'Function' ? this.que[i] : this.que[i].toString()) { | ||
delete this.que[i] | ||
removed++; | ||
} | ||
} | ||
// __returns itself for use in chaining__ | ||
return this; | ||
// __returns itself after compacting for use in chaining__ | ||
return this.compact(); | ||
} | ||
@@ -82,4 +116,7 @@ } | ||
// **executeQue** Executes the que, you should not need to call | ||
// this function directly, but on the offchance you need to | ||
// this function directly, for example if `data` doesnt exist | ||
// you will not be able to consume/output properly. | ||
// `run` makes sure data exists. On the offchance you need to | ||
// bypass the promise system its avialable `que.executeQue()` | ||
// but remember to pass in `data` and `done` if needed. | ||
enQue.prototype.executeQue = function(data, done) { | ||
@@ -90,4 +127,4 @@ // Allow ques that dont need to consume data. | ||
var orig = done; | ||
// `i` is our iterator, quit/inject check if we need to quit/inject `Promise`. | ||
var i = 0, quit = false, inject = false; | ||
// `i` is our iterator, quit/inject check if we need to quit/inject `Function`. | ||
var i = 0, quit = false, inject = false, injectFn = false; | ||
// The reduceRight function allows us to itterate through the que while constantly | ||
@@ -103,13 +140,17 @@ // nesting callbacks using the accumulator, it has very reasonable performance. | ||
// send the data forward, bellow var i is current callback index being nested. | ||
if(options === 0) return next = orig; | ||
if(options !== data && options === Object(options)) { | ||
if((!options.promise && !options.inject) && !options.quit) | ||
throw new Error(`${options} is not supported, valid fomat could be +n, -n, 0, or, {quit:+n}, {inject:+n,promise:Promise}`) | ||
else if(options.quit) | ||
quit = i + options.quit; | ||
else if(options.inject) | ||
inject = i + options.inject; | ||
if((!options.function && !options.inject) && !options.quit) | ||
throw new Error(`${options} is not supported, valid fomat could be +n, -n, 0, or, {quit:+n}, {inject:+n,function:Function}`) | ||
else if(options.quit) { | ||
quit = options.quit; | ||
} | ||
else if(options.inject) { | ||
inject = options.inject - 1; | ||
injectFn = options.function; | ||
} | ||
} | ||
else if(options !== data && options) { | ||
// creates a temp que to hold our new que. | ||
tmpQue = []; | ||
let tmpQue = []; | ||
// let `j` be the position we are skipping to. | ||
@@ -138,21 +179,21 @@ // lets say `next(-3)` was passed, so `options = -3`. | ||
// the checker variable. | ||
if(quit) { | ||
if(quit > i) { next = orig; quit = false } | ||
else quit++ | ||
if(quit !== false) { | ||
if(quit === 0) { next = orig; quit = false } | ||
else quit--; | ||
} | ||
// if inject is specified, checks if we need to inject | ||
// the `Promise` if so waits for promsise resolution and then | ||
// the `Function` if so waits for promsise resolution and then | ||
// calls `next`, otherwise increment checker and call next. | ||
if(inject) { | ||
if(inject > i) { | ||
options.promise.then(data => { | ||
next(done, data, orig, i++); | ||
}) | ||
if(inject !== false) { | ||
if(inject === 0) { | ||
next(data, done, i++, orig); | ||
injectFn(data); | ||
injectFn = inject = false; | ||
} else { | ||
inject++ | ||
next(done, data, orig, i++) | ||
inject--; | ||
next(data, done, i++, orig); | ||
} | ||
} else { | ||
// no special object options were specified just proceeds. | ||
next(data, done, orig, i++) | ||
next(data, done, i++, orig) | ||
} | ||
@@ -172,2 +213,3 @@ } | ||
enQue.prototype.run = function(data) { | ||
if(!data) data = {}; | ||
return new Promise((resolve, reject) => { | ||
@@ -174,0 +216,0 @@ try { |
{ | ||
"name": "enque", | ||
"version": "1.0.5", | ||
"version": "1.1.0", | ||
"description": "Run asynchonous functions in succession while potentially operating on the same data.", | ||
@@ -5,0 +5,0 @@ "main": "enQue.js", |
102
README.md
@@ -43,5 +43,103 @@ # enQue.js | ||
# Usage example | ||
# Usage examples | ||
```javascript | ||
// For the purpose of these examples, assume each function is asynchronous and you don't know when it will finish execution. | ||
// When operating on data it is important to remember that the data must not be a primitive. If you must operate on just a primitive | ||
// set it to an attribute to an object. for example if you need to operate on a `Number` you can do `que.run({data.number=17})`. | ||
que = require('./enQue.js') | ||
que = new que() | ||
function fn1(data, next) { | ||
console.log(1) | ||
next() | ||
} | ||
function fn2(data, next) { | ||
console.log(2) | ||
next() | ||
} | ||
que.add(fn1) | ||
que.run() // 1 | ||
que.clear() | ||
que.add([fn1, fn1, fn1]) | ||
que.run() // 1 1 1 | ||
que.clear() | ||
que.fill(fn1, 7) | ||
que.run() | ||
que.clear() // 1 1 1 1 1 1 1 | ||
que.add([fn1, fn1, fn1]) | ||
que.remove(fn1) | ||
que.run() // "" | ||
que.add([fn1, fn2, fn2, fn2]) | ||
que.remove([fn1, fn2], 3) // for best preformance only pass in numbers i.e. `remove(0); remove(1); remove(2)` | ||
que.run() // 2 | ||
que.clear() | ||
que.add([(d,n)=>n(5), fn1, fn1, fn1, fn1, fn1, fn1]) | ||
que.run() // 1 | ||
que.clear() | ||
que.add([(d,n)=>n({quit:3}), fn1, fn1, fn1, fn2, fn2, fn2]) | ||
que.run() // 1 1 1 | ||
que.clear() | ||
que.add((d,n,i)=>{console.log("hi"); n()}) | ||
que.remove('(d,n,i)=>{console.log("hi"); n()}') | ||
que.run() // "" | ||
fn5 = (data, next, index, done) => { | ||
console.log(index) | ||
index === 2 ? next(0) : next() | ||
// instead of next(0) you can use done() | ||
} | ||
que.add([fn5, fn5, fn5, fn5, fn5]) | ||
que.run() // 0 1 2 | ||
que.clear() | ||
fn3 = (data, next) => { | ||
data.data = "SEVEN"; | ||
next(); | ||
} | ||
que.add([(d,n)=>n({inject:5, function: function(d){d.data="7"}}), fn3, fn3, fn3, fn3, fn3]) | ||
que.run().then(res=>console.log(res)) // d.data === 7 | ||
// To initialise the date use `run(data)` where data is an Object. | ||
que.clear() | ||
``` | ||
Executing the above code as is gives: | ||
``` | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
1 | ||
2 | ||
1 | ||
1 | ||
1 | ||
1 | ||
0 | ||
1 | ||
2 | ||
{ data: '7' } | ||
``` | ||
# More examples | ||
```javascript | ||
// USAGE EXAMPLE | ||
@@ -98,3 +196,3 @@ const Que = require('enQue'); | ||
The above code when executed prints | ||
Executing the above code as is gives: | ||
@@ -101,0 +199,0 @@ ``` |
13202
206
200