admin管理员组

文章数量:1391977

I have multiple functions inside my route and want to execute them in order for eg the control should only move to the next function if the previous function has been successfully executed. For eg refer the below code, I wish to execute task1 first followed by task 2 and so on. Setting a timeout or await doesn't seem to be an efficient way, do I need to add async functions or something similar?

Code.js

   var task1 = cp.exec('docker images', function (error, stdout, stderr) {
        console.log('Version: ' +version);
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });    


    var task2 = cp.exec('docker pull mongo:'+version, function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });


    var task3 = cp.exec('docker run -d -p '+port2+':27017 -v '+volumeLoc+' --name '+containerName+' mongo:'+version, function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });


    var task4 = cp.exec('docker ps | grep mongo', function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });

I have multiple functions inside my route and want to execute them in order for eg the control should only move to the next function if the previous function has been successfully executed. For eg refer the below code, I wish to execute task1 first followed by task 2 and so on. Setting a timeout or await doesn't seem to be an efficient way, do I need to add async functions or something similar?

Code.js

   var task1 = cp.exec('docker images', function (error, stdout, stderr) {
        console.log('Version: ' +version);
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });    


    var task2 = cp.exec('docker pull mongo:'+version, function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });


    var task3 = cp.exec('docker run -d -p '+port2+':27017 -v '+volumeLoc+' --name '+containerName+' mongo:'+version, function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });


    var task4 = cp.exec('docker ps | grep mongo', function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });
Share Improve this question asked May 7, 2020 at 6:19 nomadev95nomadev95 1251 silver badge13 bronze badges 2
  • simpler way is to call each other function on previous function's callback. – code-jaff Commented May 7, 2020 at 6:22
  • You are not understanding that node will execute EVERYTHING async, unless told otherwise. nodejs/en/knowledge/getting-started/control-flow/… – Kasey Chang Commented May 7, 2020 at 6:23
Add a ment  | 

4 Answers 4

Reset to default 4

First turn each task into a function that returns a promise:

function task1() {
    let resolve, reject;
    const promise = new Promise((rs, rj) => { resolve = rs; reject = rj; });
    cp.exec('docker images', function (error, stdout, stderr) {
        console.log('Version: ' +version);
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
             console.log('exec error: ' + error);
             reject(error);
        } else {
             resolve();
        }
    });
    return promise;
}

Then wrap them all inside an async function:

async function main() {
    try {
        await task1();
        await task2();
    } catch (err) {
        // handle error here
    }
}

try cp.execSync function, it do the same thing but in synchronous manner https://nodejs/api/child_process.html#child_process_child_process_execsync_mand_options

example of usage

try {
  const result1 = cp.execSync('docker images');
  console.log('result1', result1);
  const result2 = cp.execSync('docker pull mongo');
  console.log('result2', result2);
} catch(e) {
  console.error('error occured', e);
}

You can consider using Promise chain for this type of execution. For example,

    var tas1 = function(){
        return new Promise(function(resolve) {
            // Your code
        });
    }


    var task2 = function(){
        return new Promise(function(resolve){
            // Your code
        });
    }


    var task3 = function(){
        return new Promise(function(resolve){
            // Your code
        });
    }

    //Start sequential GET using chained promises

    task1().then(task2).then(task3);

You need either callbacks or async/await.

You have already callbacks, you could call the next function right after the error checks (I guess they are somehow dependent, so maybe only exec the next step after a succesful previous mand)

if (error !== null) {
    console.log('exec error: ' + error);
} else {
    task2(); //but has to be defined upfront
}

You could also use util promisify:

const util = require('util');
const exec = util.promisify(require('child_process').exec);

try {
    const { stdout, stderr } = await exec('docker images') {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
}
catch (error) {
    console.log('exec error: ' + error);
}


// and then the other steps

本文标签: javascriptHow do I execute Node JS function in orderStack Overflow