Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make function calls in for loop synchronous

I get an array of strings in the request. Each string contains a command to be executed on the native shell.

var process = require('child_process'); 

function execCommand(req,res,callback){
 var params = req.params.list              //list is an array in the   request
 var result = '';
 var command = '';  
 for (var i = 0; i < params.length; i++) {
  command = params[i];
  cmd = process.exec(command);                        
  cmd.stdout.on('data', function(data){                       
   //push the shell output in variable result
  });
  cmd.on('close', function(code) {                            
   //convert the variable result to a valid JSON
  });
 }
 res.send(result);
};

The result of all the commands get mixed up in the result variable. How to make the function calls in the for loop synchronous?

like image 789
Paritosh Avatar asked May 06 '15 09:05

Paritosh


Video Answer


1 Answers

Use execSync instead of exec!

 for (var i = 0; i < params.length; i++) {
    command = params[i];
    result += process.execSync(command).toString();                        
 }

As others have pointed out, this might not be a very good idea as it will block the event loop and any requests that are being made. It is acceptable if the processes being executed will take a very short period of time to finish, but not otherwise.

Here is a simple pattern to control flow of asynchronous functions in a for loop... every time a process returns, params_finished increments by one. Once the number of finished processes equals the total number of processes the response is sent.

 for (var i = 0, total_params=params.length, params_finished=0; i < total_params; i++) {
    command = params[i];
    cmd = process.exec(command);                        
    cmd.stdout.on('data', function(data){                       
        //push the shell output in variable result
    });
    cmd.on('close', function(code) {                            
        //convert the variable result to a valid JSON
        params_finished++
        if(params_finished == total_params){
            res.send(result);
        }
    });
 }
like image 70
Christopher Reid Avatar answered Oct 21 '22 06:10

Christopher Reid