George George - 3 months ago 10
Node.js Question

Writing CLI: recursive function unexpected behavior

I was writing a command line interface to my node program when I encountered some unexpected behavior.

// Starts command line prompt bot
// @param {Function} callback - callback upon finshing CL inputs
function main(callback) {
this.args = []; // store CL args
this.consoleOutputs = ["Enter input1: ", "Enter input2: ", "enter input3: "];
this.nextInput = function(consoleOutputs, numInputsLeft) {
if (numInputsLeft == 0) { callback.apply(null, args); } // done, stop recursing and run callback
// write output to prompt user
process.stdout.write(consoleOutputs[consoleOutputs.length-numInputsLeft]);
process.stdin.on('readable', function() {
var text = process.stdin.read();
if (text !== null) {
console.log(numInputsLeft);
args.push(text);
// recurse to print next output and wait for next input
nextInput(consoleOutputs, numInputsLeft-1);
}
});
}

nextInput(this.consoleOutputs, consoleOutputs.length);
}


I expected numInputsLeft to decrement: 14, 13, 12, etc.
Instead, numInputs Left was stuck at 14, 14, 14, etc.

Why does this happen and how can I resolve it?

Answer

Actually the problem is the line

nextInput(consoleOutputs, numInputsLeft-1);

Here every time it will be only 3-1 = 2, because we are not storing the results anywhere. So everytime it tooks the same value.

I tried with this code and its working fine for me.

Please try this hope it helps.

function main(callback) {
this.args = []; // store CL args
this.consoleOutputs = ["Enter input1: ", "Enter input2: ", "enter input3: "];
this.numInputsLeft = consoleOutputs.length;

this.nextInput = function(consoleOutputs, numInputsLeft) {

    if (numInputsLeft == 0) {
      console.log("Ends here !!");
      process.stdin.removeAllListeners('readable')
      return callback(null, args);
    }

    console.log(consoleOutputs[consoleOutputs.length-numInputsLeft]);

    process.stdin.on('readable', function() {
        var text = process.stdin.read();
        if (text !== null) {
            args.push(text.toString().trim());
            numInputsLeft--;
            nextInput(consoleOutputs, numInputsLeft);
        }
    });
}

nextInput(this.consoleOutputs, this.numInputsLeft);
}

    main(function (arg1, arg2) {
      // console.log(arg1);
      console.log(arg2);
    });