最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Node.js AsyncPromise explanation with JIMP? - Stack Overflow

programmeradmin5浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 6

This 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);
}
发布评论

评论列表(0)

  1. 暂无评论