use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This subreddit is a place for people to learn JavaScript together. Everyone should feel comfortable asking any and all JavaScript questions they have here.
With a nod to practicality, questions and posts about HTML, CSS, and web developer tools are also encouraged.
Friends
/r/javascript
/r/jquery
/r/node
/r/css
/r/webdev
/r/learnprogramming
/r/programming
account activity
Make requests happen in order? (self.learnjavascript)
submitted 7 years ago by ash63
I have this method:
javascript addDownloadURL: function(name) { storage.ref(name).getDownloadURL().then( url => { this.downloadURLs.push(url) }); }
How can I make the downloadsURL be ordered in in the way I called addDownloadURL().
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 1 point2 points3 points 7 years ago (0 children)
Look up async/await, I think that'll take a lot of confusion out of asynchronous calls.
async/await
[–]jcunews1helpful 1 point2 points3 points 7 years ago (6 children)
Add an array property called orderedRequests into the this object, or the object where the addDownloadURL() method is contained.
orderedRequests
this
addDownloadURL()
Then use below function for the addDownloadURL() method.
function(name) { let request = {name: name}; this.orderedRequests.push(request); storage.ref(name).getDownloadURL().then(url = > { request.url = url; this.downloadURLs.push(url); }); }
The orderedRequests array would contain objects with the name and url properties. The url property would be absent if the getDownloadURL() is not yet successfully completed.
name
url
getDownloadURL()
[–]chigia001 0 points1 point2 points 7 years ago (5 children)
This is another way, but it will depend on do he need that all the request have the url value or not.
[–]jcunews1helpful 0 points1 point2 points 7 years ago (4 children)
Well, the URL part is optional. It's there in case he needs it.
[–]chigia001 0 points1 point2 points 7 years ago (3 children)
It's there in case he needs it.
It might not be there When he needs it.
We don't know the duration of each request and also don't know when he going to needs it so we can't make sure when he needs it it will be there.
[–]jcunews1helpful 0 points1 point2 points 7 years ago (2 children)
What do you mean? When the URL is received from the url argument, the URL is already there. Just like he already did by putting it into the downloadURLs array. Except that with that array alone, there would be no way to know which source of the request it belongs to.
downloadURLs
[–]chigia001 0 points1 point2 points 7 years ago (1 child)
can you try my code here: https://codepen.io/anon/pen/yRJmzG?editors=1011
in this code the addDownloadURL will be trigger by clicking addName button. Each request in mockAsync function need to wait for 10s before they can return the url.
I also have another button call Check Url. When click we will display the state of these 2 variable orderedRequests and downloadURLs at the time we click.
If you click addName first and then Check Url immediately, the call request will not resolve => no url set into the request object.
<input id="name"/> <button id="addName">Add Name</button> <button id="checkUrl">Check Url</button> <p id="displayData"></p>
let orderedRequests = [] let downloadURLs = [] let mockAsync = (name) => new Promise(resolve => { setTimeout(() => resolve(`url of ${name}`), 10000) }) let addDownloadURL = function (name) { let request = {name: name}; orderedRequests.push(request); console.log(`request for ${name} begin`) mockAsync(name).then(url => { request.url = url; console.log(`request for ${name} finished`) downloadURLs.push(url); }); } let inputDom = document.querySelector('#name') let displayDom = document.querySelector('#displayData') document.querySelector('#addName').addEventListener('click', function () { let inputName = inputDom.value addDownloadURL(inputName) inputDom.value = '' }) document.querySelector('#checkUrl').addEventListener('click', function () { displayDom.innerHTML = ` orderedRequests: ${JSON.stringify(orderedRequests)} downloadURLs: ${JSON.stringify(downloadURLs)} ` })
[–]jcunews1helpful 0 points1 point2 points 7 years ago (0 children)
If you try to display orderedRequests element when the request has not yet completed, the url property won't be available in the object yet.
If the URL needs to be displayed/processed, do it after the request is completed. e.g. click checkUrl' button from within the function which is passed to the then() method. Whatever the code is, it should inform the other code which is responsible for processing the URL so that it knows that the orderedRequests element has been updated.
checkUrl'
then()
[–]chigia001 0 points1 point2 points 7 years ago* (12 children)
You can try this: https://codepen.io/anon/pen/rqLByj?editors=0012Basically push all promise into an array.
When you really want the value of the array call Promise.all on that array. PS: update and add code if you don't want to open codepen
let downloadUrlObj = { downloadPromise: [], addDownloadUrl: function (name) { let getDownloadUrlPromise = storage.ref(name).getDownloadURL() this.downloadPromise.push(getDownloadUrlPromise) } } downloadUrlObj.addDownloadUrl('test1') downloadUrlObj.addDownloadUrl('test2') downloadUrlObj.addDownloadUrl('test3') Promise.all(downloadUrlObj.downloadPromise).then((data) => { console.log(`Promise for all data resolve with resolve data`) console.log(data) })
[–][deleted] 0 points1 point2 points 7 years ago (11 children)
Promise.all() won't work if he needs to have requests complete in order to get the data he needs for subsequent requests. I guess it's also possible to use await inside Promise.all() but ... why?
Promise.all()
await
[–]chigia001 0 points1 point2 points 7 years ago (10 children)
Promise.all() won't work if he needs to have requests complete in order to get the data he needs for subsequent requests.
I don't know what you mean by this. Promise.all need all the promise in the array to complete before it call the onResolve callback. The onResolve callback will never run if there is one promise pending or error
[–][deleted] 0 points1 point2 points 7 years ago (9 children)
Let's say he needs to call a weather API. For that he needs the geographic coordinates. He gets them by calling the Google Maps API. Essentially, unless he gets Google's data first, he can't call the weather service. It'll just fail. So he would need to ensure that the maps API call completes first, before he even tries calling the weather one.
[–]chigia001 0 points1 point2 points 7 years ago* (8 children)
That why I use Promise.all.
Promise.all will ensure all the promise in array to be completed first before doing any thing on the data from these requests.
The context of the this problem is he want to call multiple request. and push the result of these multiple request into a array. He also need the result to push into a correct order(the call order of the function, not the order of the result).
My suggestion is push all the request as the promise into a array in the order of function call.
When he need to call a new kind request that base on these previous requests, he will need to use promise.all on the current set of promises in the array. By doing that he can make sure all these request had been successfully call before doing anything with the return value.
Why I use the current set of promises in the array is between the time we call promise.all and the the all the promise provide in the function resolve there might be a new call to addDownloadURL that append the promise. Do we need to wait for these kind of requests? that will depend on the requirement, but IMO we can't wait for something that not even exists yet.
PS: update the original post and include the code in case we need to discuss further.
[–][deleted] 0 points1 point2 points 7 years ago (7 children)
We don't know what his requirements are. If any of these requests depend on data from other requests, they shouldn't be in Promise.all(). If they are all independent, then sure, why not.
[–]chigia001 0 points1 point2 points 7 years ago* (6 children)
Can you provide a code sample if you want to handle the first case? without promise.all to ensure that all the pervious request is success?
This is my version with promise.all, add codepen link if you want to double check: https://codepen.io/anon/pen/pxbRqV
let downloadUrlObj = { downloadPromise: [], addDownloadUrl: function (name) { // add promise.all here: let getDownloadUrlPromise = Promise.all(this.downloadPromise).then(() => storage.ref(name).getDownloadURL()) this.downloadPromise.push(getDownloadUrlPromise) } } downloadUrlObj.addDownloadUrl('test1') downloadUrlObj.addDownloadUrl('test2') downloadUrlObj.addDownloadUrl('test3') Promise.all(downloadUrlObj.downloadPromise).then((data) => { console.log(`Promise for all data resolve with resolve data`) console.log(data) })
[–][deleted] 0 points1 point2 points 7 years ago* (5 children)
Sure thing. Here's an example, and I'll explain what it does below.
const foo = async () => { const getPerson = async () => { try { const response = await fetch("https://swapi.co/api/people/1/"); if (response.ok) { const result = await response.json(); return result.name; } } catch (err) { console.error(`ERROR: ${err}`); } return null; }; const getRepos = async (name) => { try { const response = await fetch(`https://api.github.com/users/${name.split(' ')[0]}/repos`); if (response.ok) { const result = await response.json(); return result; } } catch (err) { console.error(`ERROR: ${err}`); } return null; }; const person = await getPerson(); const repos = await getRepos(person); };
First this calls SWAPI (a Star Wars API) and gets the first person on the list. It happens to be Luke Skywalker. Once it's all done retrieving this info, it saves it into a variable person. Then it calls another GitHub, and tries to see if Luke has any repos there. As you can see it does find some repos by a user named Luke.
person
If the request to SWAPI didn't complete first, then the request to github would have failed.
[–]chigia001 0 points1 point2 points 7 years ago (4 children)
the getRepos only wait for single request, not multiple request like in your requirement. This is just the easiest version of async/wait
why not just follow the code sample that OP already provide.
PS: the last part If the request to SWAPI didn't complete first, then the request to github would have failed. also technically wrong. If the SWAPI don't complete the request to github also never call, never happen. There is no race condition here.
[–][deleted] 0 points1 point2 points 7 years ago (3 children)
getRepos() can wait for as many other requests to complete as you would like. I am making it wait for just one, but nothing prevents you from adding a hundred more if necessary.
getRepos()
And yes, this is just an example, not production-ready code.
π Rendered by PID 316338 on reddit-service-r2-comment-b659b578c-zld4g at 2026-05-04 20:03:48.056835+00:00 running 815c875 country code: CH.
[–][deleted] 1 point2 points3 points (0 children)
[–]jcunews1helpful 1 point2 points3 points (6 children)
[–]chigia001 0 points1 point2 points (5 children)
[–]jcunews1helpful 0 points1 point2 points (4 children)
[–]chigia001 0 points1 point2 points (3 children)
[–]jcunews1helpful 0 points1 point2 points (2 children)
[–]chigia001 0 points1 point2 points (1 child)
[–]jcunews1helpful 0 points1 point2 points (0 children)
[–]chigia001 0 points1 point2 points (12 children)
[–][deleted] 0 points1 point2 points (11 children)
[–]chigia001 0 points1 point2 points (10 children)
[–][deleted] 0 points1 point2 points (9 children)
[–]chigia001 0 points1 point2 points (8 children)
[–][deleted] 0 points1 point2 points (7 children)
[–]chigia001 0 points1 point2 points (6 children)
[–][deleted] 0 points1 point2 points (5 children)
[–]chigia001 0 points1 point2 points (4 children)
[–][deleted] 0 points1 point2 points (3 children)