1

Starting my learning curve on NodeJS, I am trying to call a sequence of functions using async.series. Each function is a command line that is called remotely using REST.

function TestStorageDeviceBasic()
{
    scenario = [
        'cmdline1',
        'cmdline2'
    ];

    tasks = [];
    scenario.forEach(command => { tasks.push(RunCommand(sessionId,command));});
    async.series(tasks);
}

function RunCommand(sessionId, cmdLine)
{
    var options = {
        uri: `http://${domain}/api/v1/commands`,
        method: 'POST',
        json: {
            'session-id' : `${sessionId}`,
            'command-line': `${cmdLine}` 
        }
      };

      request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            log.debug(`\"${cmdLine}\" status code successful`)
            log.debug(body);
        }
        else
            log.error(`\"${cmdLine}\" status code failed`,error);
      });
}

I am getting a few problems even though the RunCommand function seems to be called.

(node:21008) UnhandledPromiseRejectionWarning: Error: expected a function
    at wrapAsync (C:\work\MyJavascriptProject\my_sample\node_modules\async\dist\async.js:198:50)
    at C:\work\MyJavascriptProject\my_sample\node_modules\async\dist\async.js:2952:13

Why RunCommand is not considered a function?

2
  • 1
    You are calling RunCommand and pushing the result of the function into tasks. The result of RunCommand is not a function. You might try using .bind() to make a function with the captured parameters. Commented Jan 4, 2020 at 18:36
  • Just a comment about using async third parties: better use async await (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) Commented Jan 4, 2020 at 19:40

2 Answers 2

1

There are three things you need to modify in the code

  • Wrap the RunCommand in a function and then push it in tasks array
  • Make sure you pass callback while wrapping up
  • Modify the RunCommand to have a callback as well so that async.series can use the output from the callbacks.

Since you are not passing callback for your RunCommand, it is only getting executed once as async.series doesn't know when to proceed ahead. The modified code would look like

function TestStorageDeviceBasic() {
  scenario = ["cmdline1", "cmdline2"];

  tasks = [];
  scenario.forEach(command => {
    tasks.push(callack => RunCommand(sessionId, command, callack));
  });
  async.series(tasks, (err, data) => {
    if (err) {
      console.error(err);
    }
    console.log(data);
  });
}

function RunCommand(sessionId, cmdLine, callack) {
  var options = {
    uri: `http://${domain}/api/v1/commands`,
    method: "POST",
    json: {
      "session-id": `${sessionId}`,
      "command-line": `${cmdLine}`
    }
  };

  request(options, function(error, response, body) {
    if (!error && response.statusCode == 200) {
      log.debug(`\"${cmdLine}\" status code successful`);
      log.debug(body);
      callack(null, body);
    } else {
      log.error(`\"${cmdLine}\" status code failed`, error);
      callack(error, null);
    }
  });
}

Hope this helps

Sign up to request clarification or add additional context in comments.

4 Comments

Thx. So when doing that, i get "Error: Callback was already called" with the stack trace. This where I am stuck for the last hour.
Where exactly are you getting this error? it is working fine for me. see this - repl.it/repls/PrevailingAshamedUtilities It is not exactly same but enough to give you an idea
could it because the next line was using err instead of error? I have updated the code. Also worth checking if log.error line is not giving any error.
I had a silly error in my code such that the braces was missing and the callback was always code. Perfect, thx a lot.
1

It's because you're calling RunCommand and then pushing its return value into tasks. Instead, push a function that makes the call:

scenario.forEach(command => { 
    tasks.push(() => RunCommand(sessionId,command));
});

2 Comments

Actually it did solve the problem, but only the first function is being called after calling async.series(tasks)
@isaac.hazan - see my answer, that has explanation of why you are seeing that behavior. Hope that helps.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.