Я работаю над ботом Discord, который берет загруженное вложение изображения, сохраняет его во временный файл после редактирования, а затем загружает на сервер Discord. Все работает, кроме тайминга. Функция sendImage вызывается после функции generateImagePixel, но пытается загрузить временное изображение до завершения работы jimp.write, вызывая ошибку ENOENT. Как мне исправить проблему с синхронизацией?
client.on('message', message => {
if (message.content.includes(config.prefix + 'pixel')) {
var tempname = d.getTime();
console.info(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.info(err);
}
});
resolve(name)
})
}
function sendImage(tempname, msg) {
msg.channel.send({
file: './temp/'+ tempname + '.png' // Or replace with FileOptions object
});
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это типичный пример выполнения асинхронных функций в синхронном цикле.
jimp.read является асинхронным, поэтому каждый вызов возвращается непосредственно перед завершением фактического выполнения. Следовательно, msg.forEach также завершает работу до завершения jimp.
Если вы используете что-то асинхронное, все, что вы делаете, должно быть в асинхронном стиле:
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);
}