Reputation: 413
I still confused about how to use promises. I have a for loop call an asynchronous method which returns a value. I use this value to push into an array. But when I print the array it is empty. Here is what I did:
async function getLink(link) {
var browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto(LINK)
const result = await page.evaluate( async() => {
let data = [];
const $ = window.$;
$('#gallery_01 .item').each(function(index, product) {
data.push($(product).find('a').attr('data-image'));
});
return data;
});
await browser.close();
return result;
}
var final = [];
for (var i = 0; i < 10; i++) {
var data = getLink(value[i].url).then(function(data) {
console.log(data); // urls show here
final.push(data);
});
}
Promise.all(final).then(() => {
console.log(final) // empty
})
The final
show empty. What did I do wrong with Promise? Pls help!
Upvotes: 1
Views: 79
Reputation: 370
Update: My bad, got a bit confused. The following code would only work without () =>
after the var fn
You are very close. Try this:
var final = [];
var results = []; // you need a separate array for results
for (var i = 0; i < 10; i++) {
// renamed the variable, changed 'data' to 'fn'
var fn = () => getLink(value[i].url).then(function(data) {
console.log(data); // urls show here
results.push(data);
});
final.push(fn);
}
Promise.all(final).then(() => {
console.log(results)
})
Promise.all accepts an array of promises. You have an array 'final' but seem to try to store the result of the fucntion execution as well as the function itself.
To do this correctly - first get an array of promises. Then pass them to Promise.all().
P.S. Assuming your function actually works, haven't looked at it, since the question was about promises.
Upvotes: 1
Reputation: 731
I can't see what value
is, but it looks like it's supposed to be an array of objects with a url
property?
Assuming the getLink() function is okay, try this for your loop:
const final = [];
for (var i = 0; i < 10; i++) {
final.push(getLink(value[i].url));
}
Promise.all(final)
.then(data => {
console.log(data);
});
Or a slightly more compact way of accomplishing the same thing:
const promises = value.map(v => getLink(v.url));
Promise.all(promises)
.then(data => {
console.log(data);
});
Upvotes: 2