I have a scenario where I would like to send in 2 or more functions (as parameters) into a handler function, and have that handler function execute each passed function as a callback function for the preceding function.
Here is a general concept of the function I am trying to write:
function functionChain() {
// MAKE SURE WE HAVE AT LEAST 1 PARAMETER
if ( arguments.length < 1 ) { return; }
// for each parameter, call it (as a function)
for ( var i=0; i<arguments.length; i++) {
if ( typeof arguments[i] === 'function' ) {
call arguments[i];
}
}
}
// example
functionChain( function1, function2, function3 );
... so in the code above, each function will be called in succession.
Where I am getting stuck is how to treat each call as a callback when the previous function completes.
The way I would approach this is to have a variable (for simplicity, lets just say a global variable named functionChainComplete), and wait to launch the next function -- and of course, each function I call would set functionChainComplete to true. So, something like this:
// set global var for tracking
var functionChainComplete;
function functionChain() {
// MAKE SURE WE HAVE AT LEAST 1 PARAMETER
if ( arguments.length < 1 ) { return; }
// SET GLOBAL VAR TO FALSE
functionChainComplete = true;
// for each parameter, call it (as a function)
for ( var i=0; i<arguments.length; i++) {
if ( typeof arguments[i] === 'function' ) {
if ( functionChainComplete == true ) {
// call the next function and wait for true again
functionChainComplete = false;
call arguments[i];
} else {
// try again in 50 ms (maybe setTimeout)?
}
}
}
}
function1() {
// do something, and when done, reset functionChainComplete
functionChainComplete = true;
}
function2() {
// do something, and when done, reset functionChainComplete
functionChainComplete = true;
}
function3() {
// do something, and when done, reset functionChainComplete
functionChainComplete = true;
}
// example
functionChain( function1, function2, function3 );
As you can see, the code above does not address the callback piece, and I am not sure where to take it from here - I suspect some sort of recursive function? I am stuck.
Something like this? (See comments, but fairly self-explanatory.)
Example:
That said, one of the reasons for promises is to allow composing possibly-async functions. If your functions returned promises, we'd use the
reduce
idiom:This could be done with nsynjs:
See https://github.com/amaksr/nsynjs/tree/master/examples for more examples.
Say you have some function,
double
, that takes an argument,x
, and a callback,k
Now say we want to run it 3 times in a row
But of course we had to statically code each continuation (
y => ...
, andz => ...
). How would we make this work with a variable amount (array) of functions?This is ripe for some abstraction tho, and introduces my favourite monad, the Continuation Monad.
If you have freedom to change the functions you're chaining, this cleans up a little bit more – here,
double
has 1 parameter and returns aCont
instead of taking a callback as a second argumentOf course if
double
was actually asynchronous, it would work the same