I'm working on a Discord bot that takes an uploaded picture attachment, saves it to a temporary file after editing, and then uploads it to the Discord server. Everything works, except for the timing. The sendImage
function gets called after the generateImagePixel
function, but tries to upload the temp image before jimp.write
is finished, causing an ENOENT error. How would I fix my timing issue?
client.on('message', message => {
if (message.content.includes(config.prefix + 'pixel')) {
var tempname = d.getTime();
console.log(tempname);
generateImagePixel(message.attachments, tempname).then(() => sendImage(tempname, message))
}
});
function generateImagePixel(msg, name) {
return new Promise((resolve, reject) => {
msg.forEach(a => {
try {
jimp.read(a.url, function (err, image) {
const clone = image.clone();
clone.pixelate(8)
.rgba(true)
.filterType(0)
.write('./temp/' + name + '.png');
});
} catch(err) {
console.log(err);
}
});
resolve(name)
})
}
function sendImage(tempname, msg) {
msg.channel.send({
file: './temp/'+ tempname + '.png' // Or replace with FileOptions object
});
}
I'm working on a Discord bot that takes an uploaded picture attachment, saves it to a temporary file after editing, and then uploads it to the Discord server. Everything works, except for the timing. The sendImage
function gets called after the generateImagePixel
function, but tries to upload the temp image before jimp.write
is finished, causing an ENOENT error. How would I fix my timing issue?
client.on('message', message => {
if (message.content.includes(config.prefix + 'pixel')) {
var tempname = d.getTime();
console.log(tempname);
generateImagePixel(message.attachments, tempname).then(() => sendImage(tempname, message))
}
});
function generateImagePixel(msg, name) {
return new Promise((resolve, reject) => {
msg.forEach(a => {
try {
jimp.read(a.url, function (err, image) {
const clone = image.clone();
clone.pixelate(8)
.rgba(true)
.filterType(0)
.write('./temp/' + name + '.png');
});
} catch(err) {
console.log(err);
}
});
resolve(name)
})
}
function sendImage(tempname, msg) {
msg.channel.send({
file: './temp/'+ tempname + '.png' // Or replace with FileOptions object
});
}
Share
Improve this question
asked Jul 20, 2018 at 7:50
Gman0064Gman0064
1073 silver badges13 bronze badges
1 Answer
Reset to default 6This is a typical example of executing asynchronous functions in a synchronous loop.
jimp.read
is asycnhronous, so each call returns immediately before the actual stuff it does finishes. Therefore msg.forEach
also finishes before jimp
is done.
Once you are using something asynchronous, all you do has to be in asynchronous style:
function generateImagePixel(msg, name) {
const promises = msg.map(attachment => {
return jimp.read(attachment.url)
.then(image => {
return image
.pixelate(8)
.rgba(true)
.filterType(0)
.write('./temp/' + name + '.png');
})
.catch(console.error);
});
return Promise.all(promises)
.then(() => name);
}