0

I have a object I am iterating through and making an axios call per iteration. The following two bits of code are what I have attempted. In one I am using an async function, and using await -- In the other, I am using a promises array and using Promise.all(promises) to iterate. They both have the same outcome .. The axios call is sending out 1,000 plus calls all at once, and not "waiting" or "pausing". What am I not seeing?

This is my async version.

function importProjects() {
    Object.keys(importFiles).map(async function (key) {
        await api.post(apiUrl() + "api/v2/addPin/",
            {pin: importFiles[key]})
            .then(response => {
                console.log(response.data);
        });
    });
}

This is my Promise version.

function importProjects() {
   let promises = [];
   Object.keys(importFiles).map(function (key) {
       promises.push(
           api.post(apiUrl() + "api/v2/addPin/", {
               pin: importFiles[key]
           })
       );
   });
   Promise.all(promises)
       .then(response =>
           console.log(response.data)
       );
}

Why to both versions send all my requests simultaneously?

Zak
  • 6,976
  • 2
  • 26
  • 48
  • 2
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) (appliies to `map` too, it runs the promises in parallel with no good way to await their completion. `Promise.all` also runs everything in parallel with a good way to await completion, but if you don't want parallel, use a plain `for .. of` loop as described in the dupe suggestion. – ggorlen May 08 '23 at 17:52

1 Answers1

2

In the first case, .map() is iterating over all of the keys in the object. The result of that iteration is to invoke that callback to .map() on every element, and invoking the callback performs the AJAX operation. Internally that callback may be fully prepared to await, but nothing is awaiting the callback itself.

In the second case, Promise.all awaits all of the promises, not each individual one in turn.

Take a step back...

If the goal is to iterate over a collection and, one at a time, await an operation then why not just use a simple loop? Nesting callbacks is just over-complicating things.

async function importProjects() {
  const keys = Object.keys(importFiles);
  for (const key of keys) {
    const response = await api.post(apiUrl() + "api/v2/addPin/", {pin: importFiles[key]});
    console.log(response.data);
  }
}
David
  • 208,112
  • 36
  • 198
  • 279
  • This is a much more understandable method. Just because I am using react doesn't mean I have to overthink my JS. This perfectly suits my needs! – Zak May 08 '23 at 18:11