You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决循环中await报错:await仅在async函数与模块顶层有效

解决forEach循环中使用await导致的报错问题

问题原因

你遇到的报错await is only valid in async functions and the top level bodies of modules,核心原因是forEach的回调函数并非异步函数,而await只能在标记为async的函数内部使用,普通forEach回调不满足这个执行条件。

另外你的代码还有两处细节问题需要修正:

  1. getCountry函数里的axios.get重复拼接了URL,且没有返回请求结果,导致后续无法获取有效国家信息
  2. API调用时重复写了URL,可直接复用配置对象里的url字段

解决方案

方案1:使用for...of循环(串行执行请求)

把forEach替换成for...of循环,循环体处于GetDogs这个async函数的作用域内,可直接使用await,实现串行请求(前一个请求完成后再发起下一个):

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'
        }
    };
    // 返回请求结果供上层使用
    const response = await axios(countryOptions);
    return response.data;
}

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(options);
        
        // 用for...of替代forEach,直接使用await
        for (const breed of dogBreeds.data) {
            const country = await getCountry(breed);
            console.log(`犬种${breed.name}的原产国信息:`, country);
        }
    } catch (err) {
        console.error('请求出错:', err);
    }
};

GetDogs();

方案2:给forEach回调添加async(并行执行请求)

如果希望提升效率,同时发起所有国家信息请求,可以给forEach的回调加上async,再用Promise.all收集并等待所有请求完成:

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'
        }
    };
    const response = await axios(countryOptions);
    // 返回犬种名称与对应国家信息,方便后续关联
    return { breedName: breed.name, countryInfo: response.data };
}

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(options);
        
        // 收集所有请求的Promise实例
        const countryPromises = [];
        dogBreeds.data.forEach((breed) => {
            countryPromises.push(getCountry(breed));
        });
        
        // 等待所有并行请求完成
        const results = await Promise.all(countryPromises);
        results.forEach(result => {
            console.log(`犬种${result.breedName}的原产国信息:`, result.countryInfo);
        });
    } catch (err) {
        console.error('请求出错:', err);
    }
};

GetDogs();

关键说明

  • 方案1适合API有请求频率限制的场景,串行执行不会触发限流
  • 方案2效率更高,但要注意API的并发请求限制,避免因请求过多被拦截
  • 修正了getCountry的返回逻辑,确保能拿到有效数据
  • 使用模板字符串${}替代字符串拼接,提升代码可读性

内容的提问来源于stack exchange,提问作者Ole Dybedokken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 01:48:38