Я хотел бы получить пиксели из некоторых изображений и вернуть их в виде массива. Для обработки изображений я использую https://www.npmjs.com/package/jimp. В Jimp есть асинхронная функция jimp.read(filePath), которую нужно обрабатывать с помощью await. Мой модуль чтения изображений:
const config = require('./configuration.json');
const fs = require('fs');
const path = require('path');
const jimp = require('jimp');
module.exports = readImages;
function readImages() { // Reads the image files and extracts the colors
const files = getFilesFromDirectory();
const imageFiles = filterForImageFiles(files);
return getInformationFromImageFiles(imageFiles);
}
function getFilesFromDirectory() { // Reads all the files from the directory provided from the configuration file
return fs.readdirSync(config.dirPath);
}
function filterForImageFiles(files) { // Filters an array of files for .png and .jpg files
return files.filter(file => {
const fileExtension = path.extname(file);
const isPngFile = fileExtension === '.jpg';
const isJpgFile = fileExtension === '.png';
return isPngFile || isJpgFile;
});
}
function getInformationFromImageFiles(imageFiles) { // Maps image files to image information
return imageFiles.map(imageFile => getInformationFromImageFile(imageFile));
}
async function getInformationFromImageFile(imageFile) { // Extracts information from an image file
const filePath = path.join(config.dirPath, imageFile);
const image = await jimp.read(filePath);
return getColorsFromImage(image);
}
function getColorsFromImage(image) { // Extracts the colors from an image file
const { width, height } = image.bitmap;
const colors = [,];
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
const intColor = image.getPixelColor(x, y);
const rgbaColor = jimp.intToRGBA(intColor);
colors[x, y] = rgbaColor;
}
}
return colors;
}
Когда я запускаю код, я получаю массив с двумя элементами (потому что я предоставил два изображения). Оба Promise { <pending> }. Пожалуйста, взгляните на getInformationFromImageFile, функцию async, ожидающую jimp reader.
Почему он возвращает обещание и не разрешает его? Должен ли я ждать каждую функцию и весь модуль ...?
Что вы хотите, чтобы readImages вернул?
массив файлов изображений
@ Olian04 извините, я все еще получаю обещание



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


Вы также должны await функции getInformationFromImageFile().
извините, я все еще получаю обещание
Поскольку getInformationFromImageFile помечен как async, он вернет Promise, поэтому его нужно дождаться. Вам нужно await, где он называется. Эти изменения должны это исправить:
async function getInformationFromImageFiles(imageFiles) {
const imageInfos = [];
for (let i = 0; i < imageFiles.length; i++) {
const imageFile = imageFiles[i];
imageInfos.push(await getInformationFromImageFile(imageFile));
}
return imageInfos;
}
async function readImages() {
const files = getFilesFromDirectory();
const imageFiles = filterForImageFiles(files);
return await getInformationFromImageFiles(imageFiles);
}
Да, извините, мой плохой @MarkMeyer, отредактировал ответ и, надеюсь, теперь он правильный.
извините, но я все еще получаю обещание
@Question3r При вызове readImages вам нужно будет подождать (или использовать синтаксис «тогда»), так как теперь это асинхронно, поэтому будет возвращено обещание. Вы ждете readImages?
а, спасибо, теперь работает. Но, пожалуйста, обновите свою функцию getInformationFromImageFiles(imageFiles), imageFiles.push должен быть imageInfos.push, чтобы он работал :)
Как сказал другой участник, ваша функция должна быть awaited, поэтому она вернет обещание result.
Если вы хотите избежать функции awaiting, вы можете получить результат обещания синхронным способом, например так:
let x = new Promise(function(){
//code
});
x.then(function(data){
//Promise resolved, do something
}).then(function(err){
//Promise rejected, do something
});
async/await так же, как обещания. Вы должны обрабатывать свои асинхронные возвраты так же, как вы обрабатываете промисы.
Всякий раз, когда вы вызываете асинхронную функцию, вы должны ждать ее в другой асинхронной функции или использовать .then(), как вы это делаете с промисами.
// make this function async
async function readImages() {
// Reads the image files and extracts the colors
const files = getFilesFromDirectory();
const imageFiles = filterForImageFiles(files);
// the next line is an async call - so await it
const images = await getInformationFromImageFiles(imageFiles); // array of images
return images;
}
function getFilesFromDirectory() {
// Reads all the files from the directory provided from the configuration file
return fs.readdirSync(config.dirPath);
}
function filterForImageFiles(files) {
// Filters an array of files for .png and .jpg files
return files.filter((file) => {
const fileExtension = path.extname(file);
const isPngFile = fileExtension === '.jpg';
const isJpgFile = fileExtension === '.png';
return isPngFile || isJpgFile;
});
}
// make this function async
async function getInformationFromImageFiles(imageFiles) {
// promisify all async returns
return Promise.all(imageFiles.map((imageFile) => getInformationFromImageFile(imageFile)));
}
// return async
async function getInformationFromImageFile(imageFile) {
// Extracts information from an image file
const filePath = path.join(config.dirPath, imageFile);
const image = await jimp.read(filePath);
return getColorsFromImage(image);
}
Async/Await всегда возвращает обещание, поэтому вы можете сделать что-то вроде этого:
Promise
.all(readImages())
.then(imd => console.info(imd))
.catch(error => console.info(error));`
await jimp.read(filePath)работает и ожидает разрешения вызова. Однако вы не ожидаете вызоваgetInformationFromImageFile(imageFile)вgetInformationFromImageFiles.