cloudcmd/modules/execon/lib/exec.js
2015-07-18 18:29:21 -04:00

233 lines
6.7 KiB
JavaScript

(function(global) {
'use strict';
if (typeof module === 'object' && module.exports)
module.exports = new ExecProto();
else
global.exec = new ExecProto();
function ExecProto() {
var slice = Array.prototype.slice,
/**
* function do save exec of function
* @param callback
* @param arg1
* ...
* @param argN
*/
exec = function(callback) {
var ret,
isFunc = typeof callback === 'function',
args = slice.call(arguments, 1);
if (isFunc)
ret = callback.apply(null, args);
return ret;
};
/*
* return function that calls callback with arguments
*/
exec.with = function(callback) {
var args = [].slice.call(arguments),
bind = Function.prototype.bind;
args[0] = null;
return bind.apply(callback, args);
};
/**
* return save exec function
* @param callback
*/
exec.ret = function() {
var result,
args = slice.call(arguments);
args.unshift(exec);
result = exec.with.apply(null, args);
return result;
};
/**
* function do conditional save exec of function
* @param condition
* @param callback
* @param func
*/
exec.if = function(condition, callback, func) {
var ret;
if (condition)
exec(callback);
else
exec(func, callback);
return ret;
};
/**
* exec function if it exist in object
*
* @param obj
* @param name
* @param arg
*/
exec.ifExist = function(obj, name, arg) {
var ret,
func = obj && obj[name];
if (func)
func = func.apply(obj, arg);
return ret;
};
exec.parallel = function(funcs, callback) {
var ERROR = 'could not be empty!',
keys = [],
callbackWas = false,
arr = [],
obj = {},
count = 0,
countFuncs = 0,
type = getType(funcs);
if (!funcs)
throw(Error('funcs' + ERROR));
if (!callback)
throw(Error('callback' + ERROR));
switch(type) {
case 'array':
countFuncs = funcs.length;
funcs.forEach(function(func, num) {
exec(func, function() {
checkFunc(num, arguments, arr);
});
});
break;
case 'object':
keys = Object.keys(funcs);
countFuncs = keys.length;
keys.forEach(function(name) {
var func = funcs[name];
exec(func, function() {
checkFunc(name, arguments, obj);
});
});
break;
}
function checkFunc(num, data, all) {
var args = slice.call(data, 1),
isLast = false,
error = data[0],
length = args.length;
++count;
isLast = count === countFuncs;
if (!error)
if (length >= 2)
all[num] = args;
else
all[num] = args[0];
if (!callbackWas && (error || isLast)) {
callbackWas = true;
if (type === 'array')
callback.apply(null, [error].concat(all));
else
callback(error, all);
}
}
};
/**
* load functions thrue callbacks one-by-one
* @param funcs {Array} - array of functions
*/
exec.series = function(funcs, callback) {
var fn,
i = funcs.length,
check = function(error) {
var done;
--i;
if (!i || error) {
done = true;
exec(callback, error);
}
return done;
};
if (!Array.isArray(funcs))
throw(Error('funcs should be array!'));
fn = funcs.shift();
exec(fn, function(error) {
if (!check(error))
exec.series(funcs, callback);
});
};
exec.each = function(array, iterator, callback) {
var listeners = array.map(function(item) {
return iterator.bind(null, item);
});
exec.parallel(listeners, callback);
};
exec.eachSeries = function(array, iterator, callback) {
var listeners = array.map(function(item) {
return iterator.bind(null, item);
});
exec.series(listeners, callback);
};
/**
* function execute param function in
* try...catch block
*
* @param callback
*/
exec.try = function(callback) {
var ret;
try {
ret = callback();
} catch(error) {
ret = error;
}
return ret;
};
function getType(variable) {
var regExp = new RegExp('\\s([a-zA-Z]+)'),
str = {}.toString.call(variable),
typeBig = str.match(regExp)[1],
result = typeBig.toLowerCase();
return result;
}
return exec;
}
})(this);