Why this thing :
I work on a project where I need to call many asynchronous functions to get data, chain them, execute them if conditions are met,.. and I ended up having unreadable code.
At some point, I looked at promises library like Q.js but even with such tools my code was complicated, so I decided to write something which would make my cases of use simple to read.
Code + what it does :
The whole concept is to help someone generate the code for the asynchronous calls as a string and then call eval() to run it (the latter probably being a major case of evil programming).
At the moment, it has only two functions because I am not sure how good this idea is.
First function : chain
This functions chains two asynchronous calls, optionally with a condition on the result of the first asynchronous call.
pp_chain_function = function (fname,condition_string) {
var queue=this;
var prec_result = 'result_'+queue.queue_length;
queue.queue_string += !condition_string ? '.then(function(){return '+fname+'();})'
:'.then(function('+prec_result+'){if('+prec_result+condition_string+'){return '+fname+'();}return $.when();})';
queue.length++;
return queue;
};
Second function : fail
Adds fail handler for the whole queue.
pp_fail_function = function(fname) {
var queue = this;
queue.queue_string += '.fail(function(error){return '+fname+'(error);})';
return queue;
};
Global queue prototype :
queue_object = {
pp_chain : pp_chain_function,
pp_fail : pp_fail_function
};
Initializing the queue :
pp_begin = function(){
var pp_queue = Object.create(queue_object);
pp_queue.queue_string='$.when()';
pp_queue.queue_length=0;
console.warn(pp_queue);
return pp_queue;
};
Usage case :
var chain = pp_begin(); //init the chain
chain.pp_chain('async_0').pp_chain('async_1'); //add two standard async functions
if(condition two){chain.pp_chain('async_2','.length>0');} //if external conditions and async_1 gave a result with length>0, execute async_2
chain.pp_fail('fail_handler'); //add fail handler
console.warn(chain); //replace with eval if you want to actually run it
I would love some feedback on that idea mainly, and on the code if applicable (even if there is very few).
EDIT : jsfiddle for up-to-date version
Concrete example :
Before :
if (online_mode && i_s_r) { //if sync clear collections and reload them
access.findAll()
.then(function (result) {
if (result.length > 0) {
access.remove(result, {
push: false
})
.then(function () {
access.load()
.then(function () {
callback_function(i, true);
});
});
} else {
access.load()
.then(function () {
callback_function(i, true);
});
};
})
.fail(function (errorObject) {
alert(errorObject);
});
} else {
callback_function(i, true);
After :
var q0 = begin();
if(online_mode && i_s_r){q0.chain('access.findAll()').chain('access.remove(result_1,{push: false})','.length>0').chain('access.load()').failure('alert');}
q0.chain_sync('callback_function(i,true)');
eval(q0.queue_string);