HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Idea of 'parser' to make the writing of asynchronous functions chains easier

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
chainstheideaparserasynchronousmakewritingfunctionseasier

Problem

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

Solution

Interesting question,

I find this code hard to read, I wonder what you consider unreadable code.

Some remarks on

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;
};


  • Use jsbeautifier.org, always



  • Prefixing with pp makes no good sense



  • Postfixing with _string makes little sense



  • prec_result



  • var queue=this;, you only need to re-assign this if you work with closures



  • Consider a templating function for your string building



  • That long ternary statements looks horrendous, consider splitting it over multiple lines



Some remarks on

queue_object = {
    pp_chain : pp_chain_function,
    pp_fail : pp_fail_function
};


  • You use queue_object as a prototype, consider changing the name to reflect, also, JavaScript ought to be written in lowerCamelCase: queue_object -> queueObject -> queuePrototype



Some remarks on

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


  • Indenting is messed up



  • You are putting conditions in strings..



-
I am fairly certain that either by making async_1 fail if length

The biggest elephant in the room is of course eval, you loose proper stack-traces, debugging, tooling ( jshint, jsbeautifier ), and open yourself up to all kinds of pain. I would suggest that you post one of your unreadable scripts, perhaps we can show you how to use Q so that they become readable without resorting to .. this.

Code Snippets

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;
};
queue_object = {
    pp_chain : pp_chain_function,
    pp_fail : pp_fail_function
};
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
$.when( async_0, async_1 )
  .then( async_2, fail_handler );

Context

StackExchange Code Review Q#57197, answer score: 5

Revisions (0)

No revisions yet.