Как выполнить функцию Node JS по порядку - PullRequest
3 голосов
/ 07 мая 2020

У меня есть несколько функций внутри моего маршрута, и я хочу выполнить их по порядку, например, элемент управления должен перемещаться к следующей функции, только если предыдущая функция была успешно выполнена. Например, обратитесь к приведенному ниже коду: я использую sh, чтобы сначала выполнить задачу 1, затем задачу 2 и так далее. Установка тайм-аута или ожидания не кажется эффективным способом, нужно ли мне добавлять функции asyn c или что-то подобное?

Код. 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);
        }
    });

Ответы [ 4 ]

4 голосов
/ 07 мая 2020

Сначала превратите каждую задачу в функцию, которая возвращает обещание:

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;
}

Затем оберните их все в асинхронную c функцию:

async function main() {
    try {
        await task1();
        await task2();
    } catch (err) {
        // handle error here
    }
}
3 голосов
/ 07 мая 2020

попробуйте cp.execSync функцию, она делает то же самое, но синхронно https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options

пример использования

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);
}
2 голосов
/ 07 мая 2020

Вы можете рассмотреть возможность использования цепочки обещаний для этого типа выполнения. Например,

    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);
1 голос
/ 07 мая 2020

Вам нужны либо обратные вызовы, либо async / await.

У вас уже есть обратные вызовы, вы можете вызвать следующую функцию сразу после проверки ошибок (я думаю, они как-то зависимы, поэтому, возможно, только exe c следующий шаг после успешной предыдущей команды)

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

Вы также можете использовать 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
...