Reputation: 2471
I need to call an async
function in a for
loop where every iteration 'builds' an object. At the end of the loop, this object should be resolved in a Promise
so that the next function in chain can pick it up for further processing. While the iterations get the data correctly, I am not able to collect the 'built up' object and return it. I keep getting {}
. Can you please help me resolve this?
async function imageDetailsCache(images) {
var imageData = {}; // This object is built up every iteration
var imageNo = '';
var promises = [];
//
for (let i = 0; i < images.length; i++) {
imageNo = images[i]
promises.push(
new Promise(function (resolve, reject) {
imageDetails(imageNo, 'BIG').then(function (result) {
imageData[imageNo] = { 'BIG': result }
imageDetails(imageNo, 'TINY').then(function (result) {
imageData[imageNo] = { 'TINY': result }
})
})
resolve(imageData)
})
)
}
Promise.all(promises).then(function (result) {
return result; // Always {}
})
}
Upvotes: 1
Views: 381
Reputation: 59
If you want to use Promises, then: I guess this will work:
async function imageDetailsCache(images) {
var imageData = {};
var promises = [];
for(let i = 0; i < images.length; i++) { // notice the let instead of var
promises.push(
new Promise( (resolve, reject) => {
imageDetails(images[i], 'BIG')
.catch(e => {reject(e)})
.then( rBig => {
imageDetails(images[i], 'SMALL')
.catch(e => { reject(e)})
.then( rSmall => {
imageData[images[i]] = {
'BIG': rBig ,
'SMALL': rSmall
}
resolve ({
BIG: rBig,
SMALL: rSmall
});
});
});
}
)
);
}
await Promise.all(promises);
return imageData;
}
imageDetailsCache(images).then((r) => {console.log(r)});
I do have to emphasize that using async & await properly (as https://stackoverflow.com/users/1048572/bergi suggested) it will make this code cleaner .
Personally I would do it like this:
async function imageDetailsCache(images) {
var imageData = {};
var promises = [];
for(let i = 0; i < images.length; i++) {
try {
imageData[images[i]] = {
'BIG': await imageDetails(images[i], 'BIG') ,
'SMALL': await imageDetails(images[i], 'SMALL')
}
} catch (e) {
console.log(e);
}
}
return imageData;
}
imageDetailsCache(images).then((r) => {console.log(r)});
Hope it helps!
Upvotes: 0
Reputation: 664538
Avoid the Promise
constructor antipattern! You were calling resolve
before the asynchronous things in imageDetails
had happened. And don't use then
when working with async
/await
:
async function imageDetailsCache(images) {
var imageData = {}; // This object is built up every iteration
var promises = images.map(async (image) => {
var result = await imageDetails(image, 'BIG');
imageData[image] = { 'BIG': result }
var result = await imageDetails(image, 'TINY');
imageData[image] = { 'TINY': result };
});
await Promise.all(promises);
return imageData;
}
Upvotes: 2