等到图像加载到 FS(代表文件系统的 NPM)

Wait until image is loaded on FS (NPM that stands for File-System)

我正在尝试对其进行编码,以便我可以从图像中选择主要颜色,我已经使用 NPM 完成了选择部分,但现在我需要下载图像本身。这是我正在使用的代码:

if (!message.author.bot) {
    var download = function(uri, filename, callback){
      request.head(uri, function(err, res, body){
        console.log('content-type:', res.headers['content-type']);
        console.log('content-length:', res.headers['content-length']);

        request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
      });
    };
    if (message.channel.id = "825209044313571388") {
      message.delete()
        var channel = client.channels.cache.get('222197033908436994');
          const webhooks = await message.channel.fetchWebhooks();
          const webhook = webhooks.first();
          await download(`${message.author.displayAvatarURL()}`, 'image.webp', function(){
            console.log('done');
          });
          var colorThief = new ColorThief();
          var color = colorThief.getColor("./image.webp");
          console.log(color)
          var embed = new MessageEmbed()
            .setColor(color)
            .setDescription(messag.content)
            .setTitle(message.author.username)
            .setThumbnail(message.author.displayAvatarURL())
          await webhook.send(``, {
            username: `${message.author.username}`,
            avatarURL: `${message.author.displayAvatarURL()}`,
            embeds: [embed],
          })
    }
  }

可以,但是“下载”函数后的代码运行时没有等待图片下载到系统,所以输出错误。

UnhandledPromiseRejectionWarning: Error: Image given has not completed loading

TL;DR: 我需要帮助在函数后编写我的代码以等待 FS 完成图像下载。

好吧,让我们看看这里发生了什么……:

// ...

// as an addition we can get rid of all the callback references and uses only promises
// from nodes util package

// so promisify changes all functions that use callbacks into promises, so all you do
// is give it the function that uses a callback and it will give a new promisified
// function
const promisify = require('util').promisify;

/*
 * So first I would suggest using a promise return so your function knows it has to
 * return when the callback is done
 * 
 * So we will not need the callback function in the args of download
 */
var download = function(uri, filename) {
  return promisify(request.head)(uri)
    // so promisify will bring res argument to the then call, and the err to the
    // catch call, ill show you below...
    .then((res) => {
      // like this

      // so i cannot promisify this call coz its a stream so i used a promise constructor
      return new Promise((resolve, reject) => {
        const write = request(uri).pipe(fs.createWriteStream(filename))
        // so we resolve here
        write.on('close', resolve);

        // then if something goes wrong in the stream, we reject here...
        write.on('error', reject);
      }
    });
};

if (message.channel.id = "825209044313571388") {
  message.delete();

  var channel = client.channels.cache.get('222197033908436994');

  const webhooks = await message.channel.fetchWebhooks();
  const webhook = webhooks.first();

  // so now this statement will hold the remaining execution until its done...
  await download(`${message.author.displayAvatarURL()}`, 'image.webp')
    .then(() => console.log('done'))
    // so we also then catch potential errors
    .catch((error) => console.log('oops', error));

  var colorThief = new ColorThief();
  var color = colorThief.getColor("./image.webp");
  console.log(color)
  var embed = new MessageEmbed()
    .setColor(color)
    .setDescription(messag.content)
    .setTitle(message.author.username)
    .setThumbnail(message.author.displayAvatarURL())

  await webhook.send(``, {
    username: `${message.author.username}`,
    avatarURL: `${message.author.displayAvatarURL()}`,
    embeds: [embed],
  })
}

请试一试,同时查看节点实用程序文档以获取有关 promisify函数转换器https://nodejs.org/dist/latest-v8.x/docs/api/util.html