Socket
Socket
Sign inDemoInstall

asynk

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

asynk - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

578

asynk.js
var _ = require('underscore');
/********************************************************************************/
/* Static state of task */
/********************************************************************************/
var WAITING = 0;
var WAITING_FOR_DEPENDENCY = 1;
var RUNNING = 2;
var DONE = 3;
var FAIL = 4;
/********************************************************************************/

@@ -8,301 +17,376 @@ /* Task */

var Task = function(parentStack,id,fct){
var self = this;
this.parentStack = parentStack;
this.id = id;
this.alias = null;
this.fct = fct;
this.args = [];
this.dependencies = [];
this.status = 'none';
var Task = function(parentStack, id, fct) {
var self = this;
this.parentStack = parentStack;
this.id = id;
this.alias = null;
this.fct = fct;
this.args = [];
this.dependencies = [];
this.status = WAITING;
};
Task.prototype.setCallback = function(callback){
this.callback = callback;
Task.prototype.setCallback = function(callback) {
this.callback = callback;
};
Task.prototype.execute = function(){
var self = this;
if (!this.checkDependencies()){
this.status = 'waiting for dependency';
return;
}
this.status = 'running';
Task.prototype.execute = function() {
var self = this;
if (!this.checkDependencies()) {
this.status = WAITING_FOR_DEPENDENCY;
return;
}
this.status = RUNNING;
this.args.forEach(function(arg,index){
if (arg instanceof DefArg){
switch (arg.type){
case 'order':
if (arg.value >= 0){
if (_.isUndefined(self.parentStack.results[arg.value])) {
self.status = 'waiting for dependency';
self.dependencies.push(arg.value);
}
else {
self.args[index] = self.parentStack.results[arg.value];
}
}
else if (arg.value < 0){
if (_.isUndefined(self.parentStack.results[self.id + arg.value])){
self.status = 'waiting for dependency';
self.dependencies.push(self.id + arg.value);
}
else {
self.args[index] = self.parentStack.results[self.id + arg.value];
}
}
break;
this.args.forEach(function(arg, index) {
if (arg instanceof DefArg) {
self.args[index] = arg.resolve(self);
}
});
if (this.status === RUNNING) {
this.fct.apply(null, this.args);
}
};
case 'alias':
if (arg.value === 'all') {
self.args[index] = self.parentStack.results;
}
else {
self.args[index] = self.parentStack.results[self.parentStack.aliasMap[arg.value]];
}
break;
case 'callback':
self.args[index] = self.callback;
break;
Task.prototype.fail = function(err) {
this.status = FAIL;
this.fct.apply(null, [err, null]);
};
case 'item':
self.args[index] = self.item;
break;
}
}
});
if (this.status === 'running') {
this.fct.apply(null,this.args);
}
Task.prototype.checkDependencies = function() {
for (key in this.dependencies) {
var id = this.dependencies[key];
if (_.isString(id)) {
id = this.parentStack.aliasMap[id];
}
if (_.isUndefined(this.parentStack.results[id])) {
return false;
}
}
return true;
};
Task.prototype.fail = function(err){
this.status = 'fail';
this.fct.apply(null,[err,null]);
/********************************************************************************/
/* Deferred Argument */
/********************************************************************************/
var DefArg = function(type, val) {
this.type = type;
this.value = val;
};
Task.prototype.checkDependencies = function(){
for (key in this.dependencies){
var id = this.dependencies[key];
DefArg.prototype.resolve = function(task) {
switch (this.type) {
case 'order':
if (this.value >= 0) {
if (_.isUndefined(task.parentStack.results[this.value])) {
task.status = WAITING_FOR_DEPENDENCY;
task.dependencies.push(this.value);
return this;
}
else {
return task.parentStack.results[this.value];
}
}
else if (this.value < 0) {
if (_.isUndefined(task.parentStack.results[task.id + this.value])) {
task.status = WAITING_FOR_DEPENDENCY;
task.dependencies.push(task.id + this.value);
return this;
}
else {
return task.parentStack.results[task.id + this.value];
}
}
break;
if (_.isString(id)) {
id = this.parentStack.aliasMap[id];
}
case 'alias':
if (this.value === 'all') {
return task.parentStack.results;
}
else {
return task.parentStack.results[task.parentStack.aliasMap[this.value]];
}
break;
if (_.isUndefined(this.parentStack.results[id])){
return false;
}
}
return true;
}
case 'callback':
return task.callback;
break;
case 'item':
return task.item;
break;
}
};
/********************************************************************************/
/* Deferred Argument */
/* progressive */
/********************************************************************************/
var Progressive = function(start, step) {
this.step = step || 1;
this.last = (_.isUndefined(start) ? 1 : start) - this.step;
this.stack = [];
};
var DefArg = function(type,val){
this.type = type;
this.value = val;
Progressive.prototype.push = function(order, fct) {
var self = this;
var task = {order: order, fct: fct};
this.stack.push(task);
return function(){
task.args = _.toArray(arguments);
var reCheck = true;
while (reCheck) {
reCheck = false;
for(i in self.stack){
var queued = self.stack[i];
if (queued.order === (self.last + self.step)) {
if (!_.isUndefined(queued.args)) {
queued.fct.apply(null, queued.args);
self.stack.slice(i, 1);
self.last += self.step;
reCheck = true;
}
else {
reCheck = false;
break;
}
}
}
}
};
};
/********************************************************************************/
/* Fifo */
/********************************************************************************/
var Fifo = function() {
this.stack = [];
};
Fifo.prototype.push = function(fct) {
var self = this;
var task = {};
task.fct = fct;
this.stack.push(task);
return function() {
task.args = _.toArray(arguments);
if (self.stack[0] === task) {
while (self.stack.length && !_.isUndefined(self.stack[0].args)) {
var callback = self.stack.shift();
callback.fct.apply(null, callback.args);
}
}
};
};
/********************************************************************************/
/* Asynk */
/********************************************************************************/
var Asynk = function(){
var Asynk = function() {
var self = this;
this.tasks = [];
this.aliasMap = [];
this.results = [];
this.currentTasks = [];
this.tasks = [];
this.aliasMap = [];
this.results = [];
this.currentTasks = [];
};
Asynk.prototype.add = function(fct){
var newId = this.tasks.length;
this.tasks[newId] = new Task(this,newId,fct);
this.currentTasks = [newId];
return this;
Asynk.prototype.add = function(fct) {
var newId = this.tasks.length;
this.tasks[newId] = new Task(this, newId, fct);
this.currentTasks = [newId];
return this;
};
Asynk.prototype.each = function(datas,fct){
var self = this;
datas.forEach(function(data){
var newId = self.tasks.length;
self.tasks[newId] = new Task(self,newId,fct);
self.tasks[newId].item = data;
self.currentTasks.push(newId);
});
return this;
Asynk.prototype.each = function(datas, fct) {
var self = this;
datas.forEach(function(data) {
var newId = self.tasks.length;
self.tasks[newId] = new Task(self, newId, fct);
self.tasks[newId].item = data;
self.currentTasks.push(newId);
});
return this;
};
Asynk.prototype.args = function(){
args = _.toArray(arguments);
var self = this;
this.currentTasks.forEach(function(currentTask){
self.tasks[currentTask].args = _.clone(args);
});
return this;
Asynk.prototype.args = function() {
args = _.toArray(arguments);
var self = this;
this.currentTasks.forEach(function(currentTask) {
self.tasks[currentTask].args = _.clone(args);
});
return this;
};
Asynk.prototype.require = function(dependency){
var self = this;
this.currentTasks.forEach(function(currentTask){
var current = self.tasks[currentTask];
current.dependencies.push(dependency);
});
return this;
Asynk.prototype.require = function(dependency) {
var self = this;
this.currentTasks.forEach(function(currentTask) {
var current = self.tasks[currentTask];
current.dependencies.push(dependency);
});
return this;
};
Asynk.prototype.alias = function(alias){
if (_.isString(alias)) {
var self = this;
this.currentTasks.forEach(function(currentTask,index){
if (self.currentTasks.length > 1){
alias += index;
}
self.tasks[currentTask].alias = alias;
self.aliasMap[alias] = currentTask;
});
}
return this;
}
Asynk.prototype.alias = function(alias) {
if (_.isString(alias)) {
var self = this;
this.currentTasks.forEach(function(currentTask, index) {
if (self.currentTasks.length > 1) {
alias += index;
}
self.tasks[currentTask].alias = alias;
self.aliasMap[alias] = currentTask;
});
}
return this;
};
Asynk.prototype.serie = function(endcall,endcallArgs){
var self = this;
var endTask = new Task(this,'end',endcall);
endTask.args = endcallArgs || this.results;
var cb = function(err, data) {
if (!err) {
self.results.push(data);
self.next();
}
else {
endTask.fail(err);
}
};
this.next = function(){
var current = self.tasks.shift();
if (current){
current.setCallback(cb);
current.execute();
}
else {
endTask.execute();
}
};
this.next();
return this;
Asynk.prototype.serie = function(endcall, endcallArgs) {
var self = this;
var endTask = new Task(this, 'end', endcall);
endTask.args = endcallArgs || this.results;
var cb = function(err, data) {
if (!err) {
self.results.push(data);
self.next();
}
else {
endTask.fail(err);
}
};
this.next = function() {
var current = self.tasks.shift();
if (current) {
current.setCallback(cb);
current.execute();
}
else {
endTask.execute();
}
};
this.next();
return this;
};
Asynk.prototype.parallel = function(endcall,endcallArgs){
var self = this;
var endTask = new Task(this,'end',endcall);
endTask.args = endcallArgs || this.results;
Asynk.prototype.parallel = function(endcall, endcallArgs) {
var self = this;
var endTask = new Task(this, 'end', endcall);
endTask.args = endcallArgs || this.results;
var count = 0;
var todo = self.tasks.length;
var cb = function(task,err,data){
task.status = 'done';
if (!err) {
self.results[task.id] = data;
count++;
if (count >= todo) {
endTask.execute();
}
else {
self.tasks.forEach(function(task) {
if (task.status === 'waiting for dependency') {
task.execute();
}
});
}
}
else {
endTask.fail(err);
}
};
var count = 0;
var todo = self.tasks.length;
var cb = function(task, err, data) {
task.status = DONE;
if (!err) {
self.results[task.id] = data;
count++;
if (count >= todo) {
endTask.execute();
}
else {
self.tasks.forEach(function(task) {
if (task.status === WAITING_FOR_DEPENDENCY) {
task.execute();
}
});
}
}
else {
endTask.fail(err);
}
};
this.tasks.forEach(function(task) {
task.setCallback(function(err,data){
cb(task,err,data);
});
});
this.tasks.forEach(function(task) {
task.setCallback(function(err, data) {
cb(task, err, data);
});
});
this.tasks.forEach(function(task) {
task.execute();
});
this.tasks.forEach(function(task) {
task.execute();
});
return this;
return this;
};
Asynk.prototype.parallelLimited = function(limit,endcall,endcallArgs){
var self = this;
var endTask = new Task(this,'end',endcall);
endTask.args = endcallArgs || this.results;
Asynk.prototype.parallelLimited = function(limit, endcall, endcallArgs) {
var self = this;
var endTask = new Task(this, 'end', endcall);
endTask.args = endcallArgs || this.results;
var count = 0;
var todo = self.tasks.length;
var cb = function(task,err,data){
task.status = 'done';
if (!err) {
self.results[task.id] = data;
count++;
if (count >= todo) {
endTask.execute();
}
else {
self.tasks.forEach(function(task) {
var stats = _.countBy(self.tasks, function(task) {
return task.status;
});
var running = stats.running || 0;
if ((running < limit) && (task.status !== 'done') && (task.status !== 'running') && (task.status !== 'fail')) {
task.execute();
}
});
}
}
else {
endTask.fail(err);
}
};
var count = 0;
var todo = self.tasks.length;
var cb = function(task, err, data) {
task.status = 'done';
if (!err) {
self.results[task.id] = data;
count++;
if (count >= todo) {
endTask.execute();
}
else {
self.tasks.forEach(function(task) {
var stats = _.countBy(self.tasks, function(task) {
return task.status;
});
var running = stats[RUNNING] || 0;
if ((running < limit) && (task.status < RUNNING)) {
task.execute();
}
});
}
}
else {
endTask.fail(err);
}
};
this.tasks.forEach(function(task) {
task.setCallback(function(err,data){
cb(task,err,data);
});
});
this.tasks.forEach(function(task) {
task.setCallback(function(err, data) {
cb(task, err, data);
});
});
this.tasks.forEach(function(task) {
var stats = _.countBy(self.tasks, function(task) {
return task.status;
});
var running = stats.running || 0;
if ((running < limit) && (task.status !== 'done') && (task.status !== 'running') && (task.status !== 'fail')) {
task.execute();
}
});
this.tasks.forEach(function(task) {
var stats = _.countBy(self.tasks, function(task) {
return task.status;
});
var running = stats[RUNNING] || 0;
if ((running < limit) && (task.status < RUNNING)) {
task.execute();
}
});
return this;
return this;
};
/*
Asynk.prototype.getTask = function(id){
if (_.isString(id)) {
if (_.) {
id = this.aliasMap[id];
}
}
return this.tasks[id];
}*/
module.exports = {
add: function(fct){
return new Asynk().add(fct);
},
each: function(datas,fct){
return new Asynk().each(datas,fct);
},
callback: new DefArg('callback'),
data: function(val){
if (_.isString(val)) {
return new DefArg('alias',val);
}
else {
return new DefArg('order',val);
}
},
item: new DefArg('item')
add: function(fct) { return new Asynk().add(fct); },
each: function(datas, fct) { return new Asynk().each(datas, fct); },
callback: new DefArg('callback'),
data: function(val) {
if (_.isString(val)) {
return new DefArg('alias', val);
}
else {
return new DefArg('order', val);
}
},
item: new DefArg('item'),
fifo: function(){ return new Fifo(); },
progressive: function(start,step){ return new Progressive(start,step); }
};
{
"name": "asynk",
"version": "0.0.1",
"version": "0.0.2",
"description": "flow control library for javascript",

@@ -5,0 +5,0 @@ "main": "asynk.js",

@@ -1,5 +0,7 @@

# Asynk.js
![asynk.js](http://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Break_dance.svg/512px-Break_dance.svg.png)Asynk.js
--------
Asynk is small tool for javascript asynchronous task management.
Asynk is a small tool for javascript asynchronous task management.
## Example

@@ -29,6 +31,12 @@

Asynk command must start be adding one or more task using functions:
Asynk command **must** start by adding one or more task using functions:
### Add
*add(fct)*
add one task
arguments:
* fct: an asynchronous function
```javascript

@@ -41,3 +49,10 @@ asynk.add(my_function).args(my_first_argument,asynk.callback) //...

### Each
*each(array_data,fct)*
add a task per array's item of the same function
arguments:
* array_data: an array of data
* fct: an asynchronous function
```javascript

@@ -54,15 +69,90 @@ asynk.each([0,1,2],my_function).args(asynk.item,asynk.callback) //...

```
## Args
args(arg1,arg2,...)
### Args
*args(arg1,arg2,...)*
arguments:
* arg1: the first argument of the task function
* arg2: the second argument of the task function
* ...
the args function define arguments of function passed to the task.
simply pass arguments like executing the function and replace the callback function by *asynk.callback*
## Execute them
```javascript
asynk.add(my_function).args(0,asynk.callback) //...
```
will execute the function like this :
```javascript
function callback(err,data){
//the callback function
}
my_function(0,callback); //...
```
#### Data
*asynk.data(task)*
data put output of a task to the input of another one.
arguments:
* task :
* **positive number:** return the value of task by absolute order of insertion starting by 0 (so 0 is the first,1 is the second...)
* **negative number:** return the value of task in a relative position (-1 is the first previous one)
* **string:** return the value of task named by alias(string) function
```javascript
//create a first task
asynk.add(my_function).args(0,asynk.callback)
//absolute position task data (here first one)
.add(my_function).args(asynk.data(0),asynk.callback)
//relative position task data (here the second one)
.add(my_function).args(asynk.data(-1),asynk.callback)
//assinging an alias name to this task
.add(my_function).args(0,asynk.callback).alias('here')
//alias name task data (here the fourth)
.add(my_function).args(asynk.data('here'),asynk.callback)
//...
```
### Require
*require(dependency)*
require function make task waiting an other one to finish before start.
arguments:
* dependency:
* **positive number:** require a selected task by absolute order of insertion starting by 0 (so 0 is the first,1 is the second...).
* **negative number:** require a selected task by a relative position (-1 is the first previous one).
* **string:** require a selected task named by alias(string) function.
```javascript
//create a first task
asynk.add(my_function0).args(0,asynk.callback)
//alias name task requirement (here the fifth)
.add(my_function1).args(4,asynk.callback).require('here')
//absolute position task requirement (here the fifth)
.add(my_function2).args(1,asynk.callback).require(4)
//relative position task requirement (here the third)
.add(my_function3).args(2,asynk.callback).require(-1)
//assinging an alias name to this task
.add(my_function4).args(3,asynk.callback).alias('here')
//...
```
here my_function0 and my_function4 will be execute first.
then on my_function4's end,my_function1 and my_function2 will be execute.
and so on my_function2's end,my_function3 will be execute.
## Launch the execution
Asynk command must finnish by choosing an excution mode:
### Serie
serie(function,args)
*serie(fct,args)*
arguments:
* fct: a function called once serie is finnished
* args: an array of arguments to pass to fct
in this mode,all task are execute one by one in the order they where inserted.

@@ -79,4 +169,8 @@

### Parallel
parallel(function,args)
*parallel(fct,args)*
arguments:
* fct: a function called once parallel is finnished
* args: an array of arguments to pass to fct
in this mode,all task are started at the same time.

@@ -93,4 +187,9 @@

### ParallelLimited
parallelLimited(limit,function,args)
*parallelLimited(limit,fct,args)*
arguments:
* limit: an integer number of maximum parallel task to execute
* fct: a function called once parallelLimited is finnished
* args: an array of arguments to pass to fct
in this mode,a predefined number(limit) of task are running in the same time.

@@ -106,41 +205,61 @@

## Asynchronous data between task
## Stacks
### Fifo
first pushed function are first executed
create a fifo stack object:
```javascript
asynk.add(my_function).args(0,asynk.callback)
.add(my_function).args(asynk.data(0),asynk.callback) //absolute position task data (here first one)
.add(my_function).args(asynk.data(-1),asynk.callback) //relative position task data (here the second one)
.add(my_function).args(0,asynk.callback).alias('here') //assinging an alias name to this task
.add(my_function).args(asynk.data('here'),asynk.callback) //alias name task data (here the fourth)
//...
var fifo = asynk.fifo();
```
asynk.data can take arguments like:
*push(fct)*
arguments:
* fct: a function
* **positive number:** return the value of task by absolute order of insertion starting by 0 (so 0 is the first,1 is the second...)
* **negative number:** return the value of task in a relative position (-1 is the first previous one)
* **string:** return the value of task named by alias(string) function
return a function that take fct arguments as arguments
## Advanced Task Functionality
```javascript
var result = '';
var fifo = asynk.fifo();
var f1 = fifo.push(function(err,data){result += data;});
var f2 = fifo.push(function(err,data){result += data;});
var f3 = fifo.push(function(err,data){result += data;});
var f4 = fifo.push(function(err,data){result += data;});
var f5 = fifo.push(function(err,data){result += data;});
var f6 = fifo.push(function(err,data){result += data;});
f6(null,6);
f2(null,2);
f4(null,4);
f1(null,1);
f3(null,3);
f5(null,5);
console.log(result); //123456
```
### Require
require(dependency)
### Progressive
function are executed in a predefined order
require function make task waiting an other one to finish before start.
create a progressive stack object:
```javascript
asynk.add(my_function0).args(0,asynk.callback)
.add(my_function1).args(4,asynk.callback).require('here') //alias name task requirement (here the fifth)
.add(my_function2).args(1,asynk.callback).require(4) //absolute position task requirement (here the fifth)
.add(my_function3).args(2,asynk.callback).require(-1) //relative position task requirement (here the third)
.add(my_function4).args(3,asynk.callback).alias('here') //assinging an alias name to this task
//...
var progr = asynk.progressive(start,step);
```
arguments:
* start: a number (first order to execute) default value is 1
* step: a number (step between order) default value is 1
here my_function0 and my_function4 will be execute first,then on my_function4's end,my_function1 and my_function2 will be execute.
and so on my_function2's end,my_function3 will be execute.
*push(order,fct)*
arguments:
* order: a number
* fct: a function
require can take arguments like:
* **positive number:** require a selected task by absolute order of insertion starting by 0 (so 0 is the first,1 is the second...).
* **negative number:** require a selected task by a relative position (-1 is the first previous one).
* **string:** require a selected task named by alias(string) function.
```javascript
var result = '';
var progr = asynk.progressive();
progr.push(6,function(err,data){result += data;})(null,6);
progr.push(2,function(err,data){result += data;})(null,2);
progr.push(4,function(err,data){result += data;})(null,4);
progr.push(1,function(err,data){result += data;})(null,1);
progr.push(3,function(err,data){result += data;})(null,3);
progr.push(5,function(err,data){result += data;})(null,5);
console.log(result); //123456
```

@@ -141,1 +141,30 @@ var _ = require('underscore');

.parallel(check,['each in parallel',asynk.data('all'),[0,1,2,0,1,2,0,1,2]]);
count++; //fifo
var fifo = asynk.fifo();
var result = '';
var f1 = fifo.push(function(err,data){result += data;});
var f2 = fifo.push(function(err,data){result += data;});
var f3 = fifo.push(function(err,data){result += data;});
var f4 = fifo.push(function(err,data){result += data;});
var f5 = fifo.push(function(err,data){result += data;});
var f6 = fifo.push(function(err,data){result += data;});
f6(null,6);
f2(null,2);
f4(null,4);
f1(null,1);
f3(null,3);
f5(null,5);
check('fifo',[result],['123456']);
count++; //progressive
var progr = asynk.progressive();
var result = '';
progr.push(6,function(err,data){result += data;})(null,6);
progr.push(2,function(err,data){result += data;})(null,2);
progr.push(4,function(err,data){result += data;})(null,4);
progr.push(1,function(err,data){result += data;})(null,1);
progr.push(3,function(err,data){result += data;})(null,3);
progr.push(5,function(err,data){result += data;})(null,5);
check('progressive',[result],['123456']);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc