Writing callbacks is much more fun if you make use of closures and named functions.
E.g., I can tell the nested math example[1] is good code because of how deeply indented it becomes.
1. https://github.com/scf4/callbaxx/blob/master/examples/nested...
Here's how FizzBuzz might look like:
function fizzBuzzLogic(nr, multipleOfThree, multipleOfFive) {
var print = console.log;
if(multipleOfThree && multipleOfFive) print("nr=" + nr + " FizzBuzz");
else if(multipleOfThree) print("nr=" + nr + " Fizz");
else if(multipleOfFive) print("nr=" + nr + " Buzz");
else print("nr=" + nr);
}
function fizzbuzz(cb) {
var modulo = require("modulo");
var errors = [];
var maxErrors = 3;
var maxConcurrency = 5;
var inProgress = 0;
var fizzBuzzCounter = 1;
next();
function next() {
while(cb && inProgress < maxConcurrency && fizzBuzzCounter < 100) run(++fizzBuzzCounter);
}
function run(nr) {
console.log("run: nr=" + nr);
var multipleOfThree = undefined;
var multipleOfFive = undefined;
moduloTest(3);
moduloTest(5);
function moduloTest(multipleOf) {
inProgress++;
modulo(nr, multipleOf, moduloResult);
function moduloResult(err, moduloNr) {
inProgress--;
if(err) {
errors.push(err);
if(errors.length >= maxErrors) {
if(cb) cb(errors.join("\n"));
cb = null;
}
else if(cb) moduloTest(multipleOf);
}
else {
if(multipleOf==3) multipleOfThree = (moduloNr==0);
if(multipleOf==5) multipleOfFive = (moduloNr==0);
if(multipleOfThree != undefined && multipleOfFive != undefined) {
fizzBuzzLogic(nr, multipleOfThree, multipleOfFive);
next();
}
}
}
}
}
}
I haven't polished or run the code, it for example doesn't call the cb (which is a common error in callback based code), but you get the idea. As an exercise you could rewrite it using async *function or using Promises, but I believe the benefit of Promises wouldn't be as apparent.