Reputation:
I'm not so experienced in async javascript. How can I call the commands without hardcoding the amount of commands or using eval?
var commands = [
// command 1: result: 0, stdout: ""
function (stdin, callback) {
callback(0, "");
},
// command 2: result: 1, stdout: ""
function (stdin, callback) {
callback(1, "");
},
// command 3: result: 0, stdout: ""
function (stdin, callback) {
callback(0, "");
},
// ...
];
var stdin = "foo";
var end = function (result, stdout) {
console.log(result);
console.log(stdout);
};
commands[0](stdin, function (result, stdout) {
commands[1](stdout, function (result, stdout) {
commands[2](stdout, end);
});
});
Upvotes: 2
Views: 153
Reputation: 4348
Final answer:
I'm using recursion to go through the commands array. You pass the loop function an array of commands and the last callback to be called (you can also pass as a fourth optional parameter the index of the array in which you wish to start the loop - defaults to zero).
var commands = [
// echo foo
function (stdin, callback) {
callback(0, "foo");
},
// touppercase
function (stdin, callback) {
callback(1, stdin.toUpperCase());
}
];
var stdin = "",
loop = function(commands, lastCallback, stdin, startIndex) {
(function insideLoop(i, stdout) {
commands[i](stdout, (i + 1 < commands.length) ? function(result, stdout){ insideLoop(i + 1, stdout); } : lastCallback);
})(startIndex || 0, stdin);
},
end = function (result, stdout) {
console.log(stdout);
};
loop(commands, end, stdin);
Upvotes: 1
Reputation: 236202
To let those functions run asyncronously, you need a way to invoke them by making sure that inbetween the calls, a browser (or actually any implementation) is allowed to do other stuff and things (cleanups, reflows, etc.).
That can be done with .setTimeout
in browsers or .nextTick
in nodejS.
function runAsync( list ) {
(function _worker( method ) {
method();
if( list.length ) {
setTimeout(function() {
_worker( list.shift() );
}, 100);
}
}( list.shift() ));
}
This would get called like
runAsync( commands );
and it would succesive grab the next array-entry (which is assumed a function) and execute it. After that, we check if there are more elements in that entry and if so, grab the next and call the next function. That happens within a setTimeout
call and a delay of 100ms. I choosed 100ms here, because its pretty much the timeframe which human beeings won't see any "slow-down" or "lagging".
Upvotes: 0