2

I wrote a function which spawns a process and want to log some information to the console. Function looks like this:

function receive(count) {
  var fileName = settings.flatfileName || "defaultFileName";
  for (var i = 1; i <= count; i++) {
    var csrFileName = fileName + i + ".json";
    var curlProcess = spawn('/bin/sh', ['-c', curlCommand(csrFileName, caServerUrl)]);
    curlProcess.on('close', function(code, signal) {
      if (code !== 0) {
        throw new Error("I'm sorry, I couldn't fetch certificate from CA. curl returned code " + code);
      }
      console.log("OK, I successfully fetched certificate for CSR " + csrFileName);
    });
  }
}

The problem is, if I call this function with parameter 2, I get output which looks like this:

OK, I successfully fetched certificate for CSR certificateRequest2.json
OK, I successfully fetched certificate for CSR certificateRequest2.json

Since variable csrFileName changes in every loop iteration, it seems that in console.log call it's value is always equal to the last value it received in the loop. Is it possible to get output which would look like this?

OK, I successfully fetched certificate for CSR certificateRequest1.json
OK, I successfully fetched certificate for CSR certificateRequest2.json

4 Answers 4

2

since onClose is async, you need to bind your filename.

Try with this :

function receive(count) {
  var fileName = settings.flatfileName || "defaultFileName";
  for (var i = 1; i <= count; i++) {
    var csrFileName = fileName + i + ".json";
    var curlProcess = spawn('/bin/sh', ['-c', curlCommand(csrFileName, caServerUrl)]);
    curlProcess.on('close', function(fileName, code, signal) {
      if (code !== 0) {
        throw new Error("I'm sorry, I couldn't fetch certificate from CA. curl returned code " + code);
      }
      console.log("OK, I successfully fetched certificate for CSR " + fileName);
    }.bind(this, csrFileName));
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Closures, iife and async! You have to study a bit more these concepts. This will solve your issue:

function receive(count) {
  var fileName = settings.flatfileName || "defaultFileName";
  for (var i = 1; i <= count; i++) {
    (function (i) {
      var csrFileName = fileName + i + ".json";
      var curlProcess = spawn('/bin/sh', ['-c', curlCommand(csrFileName, caServerUrl)]);
      curlProcess.on('close', function (code, signal) {
        if (code !== 0) {
          throw new Error("I'm sorry, I couldn't fetch certificate from CA. curl returned code " + code);
        }
        console.log("OK, I successfully fetched certificate for CSR " + csrFileName);
      });
    }(i));
  }
}

Comments

1

You could factor out the inner part of the loop into a separate function:

function receive(count) {
  var fileName = settings.flatfileName || "defaultFileName";
  for (var i = 1; i <= count; i++) {
    var csrFileName = fileName + i + ".json";
    curlFile(csrFileName);
  }
}

function curlFile(csrFileName) {
    var curlProcess = spawn('/bin/sh', ['-c', curlCommand(csrFileName, caServerUrl)]);
    curlProcess.on('close', function(code, signal) {
      if (code !== 0) {
        throw new Error("I'm sorry, I couldn't fetch certificate from CA. curl returned code " + code);
      }
      console.log("OK, I successfully fetched certificate for CSR " + csrFileName);
    });
 }

Comments

1

You can use closure like this

function receive(count) { var fileName = settings.flatfileName || "defaultFileName"; 
   for (var i = 1; i <= count; i++) { 

        (function(x){
            var csrFileName = fileName + x + ".json"; 
            var curlProcess = spawn('/bin/sh', ['-c', curlCommand(csrFileName, caServerUrl)]); 
            curlProcess.on('close', function(code, signal) { 
                  if (code !== 0) { 
                      throw new Error("I'm sorry, I couldn't fetch certificate from CA. curl returned code " + code); 
                 } 
                 console.log("OK, I successfully fetched certificate for CSR " + csrFileName); 
            }); 
        })(i);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.