【问题标题】:How do I execute Node JS function in order如何按顺序执行Node JS函数
【发布时间】:2020-08-22 08:35:09
【问题描述】:

我的路由中有多个函数,并且想要执行它们,例如,如果前一个函数已成功执行,控件应该只移动到下一个函数。例如参考下面的代码,我希望先执行任务1,然后执行任务2,依此类推。设置超时或等待似乎不是一种有效的方法,我是否需要添加异步函数或类似的东西?

代码.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);
        }
    });

【问题讨论】:

标签: javascript node.js docker asynchronous async-await


【解决方案1】:

首先将每个任务变成一个返回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;
}

然后将它们全部包装在一个异步函数中:

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

【讨论】:

    【解决方案2】:

    尝试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);
    }
    

    【讨论】:

    • 在使用 execSync 时,我无法 console.log 我的标准输出,它是否适用于所有功能?
    • 此函数将返回标准输出作为结果,如果发生错误则会引发错误,因此您可以以完全线性的方式使用它
    • 我有两个 console.log('stdout: ' + stdout); console.log('stderr: ' + stderr);但由于某种原因,它不会在控制台上打印任何内容。但是,每个功能的任务都在顺利执行。
    • 我已经添加了使用示例,请看看它是否有用
    • execSync 可能会返回一个字符串或缓冲区,因此请确保正确处理它。如果是缓冲区记得添加 result.toString() 到它
    【解决方案3】:

    您可以考虑使用 Promise 链进行此类执行。例如,

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

    【讨论】:

      【解决方案4】:

      您需要回调或异步/等待。

      你已经有了回调,你可以在错误检查后立即调用下一个函数(我猜它们在某种程度上是依赖的,所以可能只在上一个命令成功后执行下一步)

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 2016-04-07
        • 2020-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-29
        相关资源
        最近更新 更多