How to wait for an async function?

时间:2018-04-18 18:05:19

标签: javascript asynchronous fetch

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?

1 个答案:

答案 0 :(得分: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]);
 })()