I've got a node application that spawn
s a child_process
. When the child_process
is finished running, I'd like to resolve a promise. The following code works, but the .then()
statements occur out of order:
const storage = require('./storage');
const logging = require('./logging');
const process = require('child_process').spawn;
function convertIncomingFile(pathToFile) {
logging.info(`Converting ${pathToFile}`);
const convert = process(`cat`, [pathToFile], {});
return Promise.resolve(
convert.stdout.on('data', (data) => {
logging.info(data.toString('utf8'));
}),
convert.stderr.on('data', (err) => {
logging.error(err);
}),
convert.on('close', (code) => {
logging.info(`Conversion finished with status code ${code}`);
})
);
}
module.exports = {
convertFile: (filename) => {
storage.downloadFile(filename).
then((localFilename) => {
logging.info(`File saved to: ${localFilename}`);
}).
then(() => convertIncomingFile(`./files/${filename}`)).
then(() => {
logging.info(`Coversion of ${filename} complete.`);
}).
catch((apiErr) => {
logging.error(apiErr);
});
}
};
The output I get is:
info: File saved to: ./files/package.json
info: Converting ./files/package.json
info: Coversion of package.json complete.
info: {
<file contents>
}
info: Conversion finished with status code 0
As you can see the Conversion of package.json complete.
statement occurs before the file contents are logged and the conversion status code statement. Why is this the case and how do I get the 'Conversion complete' statement to come after the 'status code' statement?
Promise.resolve
means return a solved value that you give it, it's not realy async as you expected. Check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise for more detailed info
function convertIncomingFile(pathToFile) {
logging.info(`Converting ${pathToFile}`);
const convert = process(`cat`, [pathToFile], {});
return new Promise((resolve, reject) => {
convert.stdout.on('data', (data) => {
logging.info(data.toString('utf8'));
}),
convert.stderr.on('data', (err) => {
logging.error(err);
reject()
}),
convert.on('close', (code) => {
logging.info(`Conversion finished with status code ${code}`);
resolve()
})
})
}