JavaScript обещание не будет разрешено или отклонено, оно просто блокируется по какой-то причине - PullRequest
0 голосов
/ 09 июля 2020

Я пишу сценарий узла, который должен упорядочивать изображения по значению счет , вычисляемому функцией, называемой getImageScore(). Для вычисления этого балла требуется довольно много времени, поэтому я создал обещание (promiseImageScore), которое вернет значение счет . После получения обещанного значения по обещанию promiseImageScore программа регистрирует имя изображения и его оценку . Несмотря на создание обещания для значений score , они все равно возвращаются как undefined. Я заметил, что обещания никогда не заканчиваются sh, они просто всегда остаются в состоянии pending. Я попытался отследить, что на самом деле происходит в функции getImageScore(), записывая в журнал некоторые сообщения с помощью функции, и, как и ожидалось, эти журналы останавливаются в какой-то момент, но я не могу понять, почему это происходит. Вот полная программа:

const fs = require('fs');
const { resolve } = require('path');
const { reject } = require('q');
const { Console } = require('console');
const gm = require('gm').subClass({imageMagick: true});
const PNG = require("pngjs").PNG;
let pathToFolder = '/home/eugen/Pictures/wallpapers1';
let pathToImage = '';

let promiseImageScore = new Promise((resolve, reject) => {
  resolve(getImageScore());
});

function getImageScore() {
  console.log('entered this promise....');
  let img = gm(pathToImage);
  // Get the PNG buffer
  img.toBuffer("PNG", (err, buff) => {
    if (err) return new Error(err);
    console.log('got buffer...');
    // Get the image size
    img.size((err, size) => {
      if (err) {
        console.log(err);
        return new Error(err);
      }
      console.log('got image size...');
      // Parse the PNG buffer
      let str = new PNG();
      str.end(buff);

      // After it's parsed...
      str.on("parsed", buffer => {
        // Get the pixels from the image
        let idx, score = 0, rgb = {r: 0, g: 0, b: 0};

        for (let y = 0; y < size.height; y++)
          for (let x = 0; x < size.width; x++) {
            idx = (size.width * y + x) << 2;
            rgb.r = buffer[idx];
            rgb.g = buffer[idx + 1];
            rgb.b = buffer[idx + 2];
            score += (rgb.r + rgb.g + rgb.b) / 765;
          }
          console.log('one promised finished...');
          return score / (size.height * size.width);
      });
      str.on("error", e => {
        return new Error(e);
      });
    });
  });
}

// see which images are to be found in the specificd directory
fs.readdir(pathToFolder, function (err, files) {
    if (err) return console.log('Unable to scan directory: ' + err);
    console.log('files in directory:\n');
    files.forEach(function (file) {
        pathToImage = pathToFolder + '/' + file;
        //showImageScore();
        promiseImageScore
        .then(imageScore => {
          console.log(file + ' has a score of ' + imageScore);
        })
        .catch(e => {
          throw e;
        })
    });
});

Вот вывод кода:

entered this promise....
files in directory:

Boats_Thailand_Sea_Crag_Nature_8000x5224.jpg has a score of undefined
Wallpaper_8K_0_7680x4320.jpg has a score of undefined
Water_mountains_landscapes_nature_snow_valley_rocks_switzerland_rivers_3840x2400.jpg has a score of undefined
Waterfalls_USA_Crag_Trees_Hocking_Hills_State_Park_Ohio_Nature_10929x5553.jpg has a score of undefined
cats_blue_eyes_animals_pets_4288x2848.jpg has a score of undefined
cats_blue_eyes_animals_pets_4288x2848.png has a score of undefined
city_night_panorama_117682_3840x2160.jpg has a score of undefined
starry_sky_tree_night_sky_119989_1920x1080.jpg has a score of undefined
got buffer...

После журнала got buffer... программа продолжает работать, никогда не останавливается, очевидно, ничего не делает .

1 Ответ

1 голос
/ 09 июля 2020

Ваш код некорректно работает с обещаниями. Вам необходимо внести несколько изменений:

  1. Передайте resolve и reject в getImageScore:
const promiseImageScore = new Promise((resolve, reject) => {
  // You need to pass resolve and reject to getImageScore
  getImageScore(resolve, reject);
});
Используйте resolve и reject дюйм getImageScore:
// For example
img.toBuffer("PNG", (err, buff) => {
  // If you get an error you need to call reject and return from the function
  // You will need to do the same for img.size((err, size) => {})
  // and for str.on("error", e => {})
  if (err) return reject(err);

  // Then when you have your result and there were no errors,
  // you will need to call resolve with the result
  resolve(score / (size.height * size.width));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...