dwalin93
dwalin93

Reputation: 83

Node child process exec async only called once

I have an array with some IDs like a = [abc,cde,efg]. I pass this array and a second one containing the names with fit to the IDs to a child process in Node. I want to wait until the child process finished and processes the next array member after that.

The code to achieve it is (with the suggested Edit):

function downloadSentinel(promObj) {
return new Promise((resolve,reject) => {
    function makeRequest(url, i, callback) {
        url = promObj.ID;
        name = promObj.Name;
        var sys = require('util'),
            exec = require('child_process').exec,
            child;

        var directory = __dirname.substring(0, __dirname.indexOf("\\app_api"));
        console.log(directory);



        child = exec(directory + '\\downloadProducts.sh' + promObj.ID[i] + ' ' + promObj.Name[i], function (error, stdout, stderr) {
            child.on("error", function (error) {
                console.log(error);
            })

            child.stdout.on('data', function (data) {
                console.log(data.toString());
            });

            child.on('exit', function(exit) {
            console.log(exit);    
            callback();


            })


        })



    }

    async.eachOfLimit(promObj.requestURLS, 2, makeRequest, function (err) {
        if (err) reject(promObj)
        else {
            resolve(promObj);
        }
    });
});
}

I am using npm-async to control the concurrency flow because I want to limit the curl requests I do inside the shell script. The shell sript works without an error. Now the script is only called twice because of the async.eachOfLimit limit. Then the other array IDs are not processed anymore.

EDIT

This is the code I tried at last, but then all possible urls are evoked instead of only 2. I found this here Another Stackoverflow question. I also tried with async.timesLimit

function downloadSentinel(promObj,req,res) {
     async.eachOfLimit(promObj.requestURLS, 2,function (value,i,callback) {
         console.log('I am here ' + i + 'times');
         url = promObj.requestURLS;
         name = promObj.Name;
         console.log(promObj.requestURLS);
         var sys = require('util'),
             exec = require('child_process').exec,
             child;

         var directory = __dirname.substring(0, __dirname.indexOf("\\app_api"));
         console.log(directory);

         console.log("executing:", directory + '\\downloadProducts.sh ' + promObj.requestURLS[i] + ' ' + promObj.Name[i]);
         child = exec(directory + '\\downloadProducts.sh' + ' ' + promObj.requestURLS[i] + ' ' + promObj.Name[i], function (error, stdout, stderr) {

             if (error != null){
                 console.log(error);
             }



            // this task is resolved
            return  callback(error, stdout);
         });

     }, function (err) {
        if (err) console.log('error')
        else {
            console.log('Done');
        }
    });

     }

What have I missed? Thanks in advance.

Upvotes: 1

Views: 1489

Answers (1)

attdona
attdona

Reputation: 18933

exec is asynchronous, it does not wait for the launched process to finish.

Move the call to callback() inside the child.on('exit' ...) handler or use execSync

Upvotes: 1

Related Questions