0

I'm trying to write a function (with the fetch API) to download some files simultaneously, but return until all files are downloaded. Just cant figure out how.

This is what I have tryed.

files = ["file1.xml", "file2.xml", "file3.xml"];

let res = get_files(files);

//TypeError: res[0] is undefined 
console.log("res: " + res[0].getElementsByTagName("NAME")[0].childNodes[0].nodeValue);

function get_files(files){
  let ret_files = [];

  files.map(file => {       //Create a new anonymous array full of promises (one per fetch).
    fetch(file);            //Triger the download
  }).map(async prom => {    //Another array with promises.
    return await prom;      //Waits for ALL the files to download.
  }).forEach(p => {
    p.then(a => ret_files.push(a)); //Populate 'ret_files' array.
    //This works:
    console.log("Inside function: " + ret_files[0].getElementsByTagName("NAME")[0].childNodes[0].nodeValue);
  });

  return ret_files;
}

As far as I can see, the function get_files() is returning immediately when called. How can I wait until the ret_files array is completely populated?

algolejos
  • 129
  • 6
  • 1
    Possible duplicate of [How do I wait for a promise to finish before returning the variable of a function?](https://stackoverflow.com/questions/27759593/how-do-i-wait-for-a-promise-to-finish-before-returning-the-variable-of-a-functio) – Alex Shesterov Apr 18 '18 at 18:07

1 Answers1

2

Youve got a few problems in your code:

 files.map(file => {
   fetch(file); // triggers the download, but you dont do anything, not even return it
  }).map(async prom => // prom is undefined?
    return await prom; //Waits for undefined ?! And thats basically a noop
  }).forEach(p => { // p is undefined again
    p.then(a => ret_files.push(a)); // Why?!     
 });

 return ret_files; // you return *now* and dont wait for anything?!

And here is how it should work:

 function getFiles(files){
   return Promise.all(files.map(file => fetch(file)));
 }

That just creates an array of fetch promises, and awaits all of them.

You can use it like:

 (async function() {

   let res = await getFiles(files);
   console.log(res[0]);
 })()
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • Thank you for your great answer, but I'd like to return the content of the files, not the Promise. How can I process the promise and return AFTER I get the content of the files?? – algolejos Apr 18 '18 at 18:36
  • @algolejos thats exactly what the code above is doing. It returns a promise that resolves to an array of file contents. – Jonas Wilms Apr 18 '18 at 19:17