最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I execute Node JS function in order - Stack Overflow

programmeradmin1浏览0评论

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
发布评论

评论列表(0)

  1. 暂无评论