Reputation: 3832
I would like to get the pixels from some images and return them as an array. For the image handling I use https://www.npmjs.com/package/jimp . Jimp has an asynchronous function jimp.read(filePath)
that needs to get handled with await. My image reader module:
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;
}
When I run the code I receive an array with two items (because I provided two images). Both are Promise { <pending> }
. Please have a look at getInformationFromImageFile
which is an async
function awaiting the jimp reader.
Why does it return a promise and does not resolve it? Do I have to await every function and the whole module ... ?
Upvotes: 3
Views: 693
Reputation: 1432
Async/Await always returns Promise, so you can do something like this:
Promise
.all(readImages())
.then(imd => console.log(imd))
.catch(error => console.log(error));`
Upvotes: 0
Reputation: 1378
As getInformationFromImageFile
is marked async
it will return a Promise
therefore it must be awaited. You need to await
where it is called. These changes should fix it:
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);
}
Upvotes: 4
Reputation: 6299
async/await
is just like promises. You gotta handle your async returns like you handle promises.
Whenever you invoke an async function, you gotta await it in another async function or use .then()
like you do with promises.
// 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);
}
Upvotes: 0
Reputation: 465
As other member said, your function needs to be awaited
hence it will return the promise result
.
If you want to avoid awaiting
the function, you can get your promise result in a synchronous way, like this:
let x = new Promise(function(){
//code
});
x.then(function(data){
//Promise resolved, do something
}).then(function(err){
//Promise rejected, do something
});
Upvotes: -1
Reputation: 2376
You also need to await
the function getInformationFromImageFile()
.
Upvotes: 0