Reputation: 2031
I'm trying to figure out the most efficient way to wait inside map function until all datas are fetched and then continue. I tried with the 'bluebird' library and came out with this.
Is this even working right and is there even better way to achieve this?
let urls = ['https://static.pexels.com/photos/36753/flower-purple-lical-blosso.jpg', 'https://static.pexels.com/photos/36764/marguerite-daisy-beautiful-beauty.jpg', 'https://static.pexels.com/photos/65609/tulip-tulips-sharpness-game-flower-65609.jpeg'];
let test = [];
Promise.map(urls, function(url) {
// Promise.map awaits for returned promises as well.
return getThumb(url);
}).then(function() {
console.log(test);
});
function getThumb(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
test.push(url);
});
https://jsfiddle.net/v80wmmsv/4/
Thanks :)
Edit:
This is the final outcome:
let urls = ['https://static.pexels.com/photos/36753/flower-purple-lical-blosso.jpg', 'https://static.pexels.com/photos/36764/marguerite-daisy-beautiful-beauty.jpg', 'https://static.pexels.com/photos/65609/tulip-tulips-sharpness-game-flower-65609.jpeg'];
Promise.map(urls, getThumb).then(function(data) {
console.log(data.length);
}).catch(e => console.error(e));
function getThumb(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
};
Upvotes: 3
Views: 7234
Reputation: 1075635
Some notes about that code, which may or may not be issues depending on what you want:
test
will end up with the URLs in the order in which they were requested (which I'm fairly sure is the same as their order in the original array, looking at the Promise.map
documentation), not the order in which they were resolved (if you care)test
will contain the URLs even if they failed to load, since you're pushing them in the mapping functionYou're using an unnecessary wrapper function, no need for the wrapper around getThumb
:
Promise.map(urls, getThumb).then(function() {
console.log(test);
});
And one definite issue:
catch
(or a then
with the second [failure] callback).Other than the lack of error handling, if the above is what you want, that code is fine.
Upvotes: 1
Reputation: 11610
If you want to concurrently run all promises and do something when all of them are resolved, you can use es2015 Promise.all()
:
let urls = ['https://static.pexels.com/photos/36753/flower-purple-lical-blosso.jpg', 'https://static.pexels.com/photos/36764/marguerite-daisy-beautiful-beauty.jpg', 'https://static.pexels.com/photos/65609/tulip-tulips-sharpness-game-flower-65609.jpeg'];
let test = [];
Promise.all(urls.map(getThumb)).then(function() {
console.log(test);
});
function getThumb(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
test.push(url);
});
};
Upvotes: 2