So I have a server listening to RabbitMQ requests:
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);
});
The problem is that the await call on executing the shell script new_user_run_athena.sh
happens after I print out Finished running Athena for mongodbUserId
. You can see it happening in the console log:
[*] 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:
Is it even possible to use async await syntax on executing a shell script?
See the MDN documentation for await
:
The await operator is used to wait for a Promise. It can only be used inside an async function.
The exec
function does not return a Promise, so you cannot await for it.
You could write a function which wraps exec
in a Promise and returns that Promise though.
Since exec
looks like it takes a callback, you can use that to wrap it into a promise. Then you can await that promise instead of awaiting the exec
call directly. So, for your example, something like:
// 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();
});
});
Wrap exec in a promise. Here a typescript example:
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)
})
})
}
Usage:
const commandOutput = await exec('echo Hey there!')
console.log(commandOutput)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.