简体   繁体   中英

await is only valid in async functions and the top level bodies of modules in loop

FYI The api calls work fine as i change the SECRET to the real key.

I understand the error but not sure if I can solve this problem.

Here is an example of what I want to achieve. I am getting all dog breeds through a API call. This works fine and the array comes in after await. Now what I am trying to do is to loop through all the dog breeds and get information about the country they are from from another API. Than it tells me that

await is only valid in async functions and the top level bodies of modules

I cant have it at the top as I rely on the other result. How can this be achieved?

const axios = require('axios').default;

async function getCountry(breed){
    const countryOptions = {
        method: 'GET',
        url: 'https://countries-cities.p.rapidapi.com/location/country/'+breed.origin,
        headers: {
          'X-RapidAPI-Key': 'SECRET',
          'X-RapidAPI-Host': 'countries-cities.p.rapidapi.com'
        }
      };
      await axios.get("https://countries-cities.p.rapidapi.com/location/country/'+breed.origin",countryOptions);
}

async function GetDogs(){
    try{
        const options = {
            method: 'GET',
            url: 'https://dog-breeds2.p.rapidapi.com/dog_breeds',
            params: {limit: '2'},
            headers:{'X-RapidAPI-Key': 'SECRET',
            'X-RapidAPI-Host': 'dog-breeds2.p.rapidapi.com'}
          };
    const dogBreeds = await axios.get("https://dog-breeds2.p.rapidapi.com/dog_breeds",options);
    dogBreeds.data.forEach((breed)=>{
        const country = await getCountry(breed);
        console.log(country);
    })
    }
    catch(err){
        console.log(err);
    }
};

GetDogs();
```

You can pass an async function as a callback to the forEach method.

dogBreeds.data.forEach(async (breed)=>{
  const country = await getCountry(breed);
  console.log(country);
});

As mentioned in the comments you can use a for...of loop to stay in the same async scope of the current function block.

for (const breed of dogBreeds.data) {
  const country = await getCountry(breed);
  console.log(country);
}

But you might want to do something with the result from getCountry .

Do be aware the getCountry does not return anything.
So the the resolved Promise will yield undefined .

If you fixed that than maybe using the map method on the dogBreeds.data array might be more useful in combination with Promise.all to make the queries in parallel. The result will be an array of countries.

const countries = await Promise.all(dogBreeds.data.map((breed) => getCountry(breed)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM