Node.js 异步/Promise 与 JIMP 的解释?

Gma*_*064 0 javascript image-processing node.js discord discord.js

我正在开发一个 Discord 机器人,它会获取上传的图片附件,编辑后将其保存到临时文件,然后将其上传到 Discord 服务器。除了时间之外,一切都正常。该sendImage函数在该函数之后被调用generateImagePixel,但尝试在完成之前上传临时图像jimp.write,从而导致 ENOENT 错误。我该如何解决我的时间问题?

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
    });
}
Run Code Online (Sandbox Code Playgroud)

Luc*_* S. 6

这是在同步循环中执行异步函数的典型示例。

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);
}
Run Code Online (Sandbox Code Playgroud)