【问题标题】:How to use javascript async/await on executing shell script如何在执行 shell 脚本时使用 javascript async/await
【发布时间】:2021-02-19 01:26:33
【问题描述】:

所以我有一个服务器正在监听 RabbitMQ 请求:

        console.log(' [*] Waiting for messages in %s. To exit press CTRL+C', q);
        channel.consume(q, async function reply(msg) {
            const mongodbUserId = msg.content.toString();
            console.log(' [x] Received %s', mongodbUserId);

            await exec('./new_user_run_athena.sh ' + mongodbUserId, function(
                error,
                stdout,
                stderr
            ) {
                console.log('Running Athena...');
                console.log('stdout: ' + stdout);
                console.log('stderr: ' + stderr);
                if (error !== null) {
                    console.log('exec error: ' + error);
                }
            });

            console.log(
                ' Finished running Athena for mongodbUserId=%s',
                mongodbUserId
            );

            channel.sendToQueue(
                msg.properties.replyTo,
                new Buffer(mongodbUserId),
                { correlationId: msg.properties.correlationId }
            );

            channel.ack(msg);
        });

问题是在我打印出Finished running Athena for mongodbUserId 之后,执行shell 脚本new_user_run_athena.sh 的等待调用发生了。您可以在控制台日志中看到它发生的情况:

 [*] Waiting for messages in run_athena_for_new_user_queue. To exit press CTRL+C
 [x] Received 5aa96f36ed4f68154f3f2143
 Finished running Athena for mongodbUserId=5aa96f36ed4f68154f3f2143
Running Athena...
stdout: 
stderr:

甚至可以在执行 shell 脚本时使用 async await 语法吗?

【问题讨论】:

  • 您的代码中的exec 是什么? child_process.exec?因为它不返回承诺。所以在它上面使用await 没有任何作用。

标签: javascript shell async-await


【解决方案1】:

由于exec 看起来需要回调,因此您可以使用它来将其包装成一个承诺。然后,您可以等待该承诺,而不是直接等待 exec 调用。因此,对于您的示例,类似:

// Await a new promise:
await new Promise((resolve, reject) => {
    exec('./new_user_run_athena.sh ' + mongodbUserId, function(
        error,
        stdout,
        stderr
    ) {
        console.log('Running Athena...');
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
            // Reject if there is an error:
            return reject(error);
        }

        // Otherwise resolve the promise:
        resolve();
    });
});

【讨论】:

    【解决方案2】:

    the MDN documentation for await:

    await 运算符用于等待 Promise。它只能在异步函数中使用。

    exec 函数不返回 Promise,因此您不能等待它。

    您可以编写一个函数 which wraps exec in a Promise 并返回该 Promise。

    【讨论】:

    【解决方案3】:

    exec 包装在一个承诺中。这是一个打字稿示例:

    import { exec as childProcessExec } from 'child_process'
    
    const exec = async (command: string): Promise<string> => {
      return new Promise((resolve, reject) => {
        childProcessExec(command, (error, stdout, stderr) => {
          if (error !== null) reject(error)
          if (stderr !== '') reject(stderr)
          else resolve(stdout)
        })
      })
    }
    

    用法:

    const commandOutput = await exec('echo Hey there!')
    console.log(commandOutput)
    

    【讨论】:

      猜你喜欢
      • 2018-12-15
      • 2019-05-24
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多