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

Pathfinder API数据获取后console.log重复输出问题求助

问题分析与解决方案

核心问题原因

  1. 循环代码的重复请求根源:你最初的循环实现里,在pflibraries.forEach的每一次迭代中,先把当前子endpoint推到pathfinderLibraries数组,紧接着就遍历整个数组发起请求。比如第一个元素被添加后,数组长度为1,发起1次请求;第二个元素添加后,数组长度为2,发起2次请求(包含第一次的元素),以此类推,最终每个子endpoint会被请求N次(N是它在数组中的位置+1),自然console.log会重复输出。

  2. 手动请求的残留重复:大概率是getData()函数被多次触发执行了——比如页面加载时重复调用,或者绑定了重复的事件监听器导致函数多次运行。

修复后的批量实现代码

下面是遵循DRY原则、高效批量请求且避免重复输出的代码:

const apiKey = "API KEY WITHHELD";
// 复用请求头,避免重复编写
const requestHeaders = new Headers({
    "Authorization": apiKey,
    "Content-Type": "application/json",
    "Accept": "application/json",
    "X-Requested-With": "XMLHttpRequest",
});

async function fetchPathfinderData() {
    try {
        // 1. 获取主endpoint返回的子endpoint列表
        const mainResponse = await fetch("https://api.pathfinder2.fr/v1/pf2", {
            method: 'GET',
            headers: requestHeaders
        });
        const subEndpoints = await mainResponse.json();

        // 2. 并行请求所有子endpoint,避免串行等待浪费时间
        const dataPromises = subEndpoints.map(endpoint => 
            fetch(endpoint, {
                method: 'GET',
                headers: requestHeaders
            }).then(res => res.json())
        );

        // 3. 等待所有请求完成,获取所有数据
        const allData = await Promise.all(dataPromises);

        // 4. 关联endpoint和对应数据,方便后续处理,且只输出一次
        subEndpoints.forEach((endpoint, index) => {
            console.log(`=== ${endpoint.split('/').pop()} 数据 ===`);
            console.log(allData[index]);
        });

        // 这里可以把allData用于你的搜索页面逻辑
        return allData;
    } catch (error) {
        console.error("请求出错:", error);
    }
}

// 确保函数只执行一次,比如放在页面加载完成后
document.addEventListener('DOMContentLoaded', () => {
    fetchPathfinderData();
});

手动请求代码的优化建议

如果你暂时不想用批量循环,也可以优化手动请求的代码,同时避免重复执行:

const apiKey = "API KEY WITHHELD";
const requestHeaders = new Headers({
    "Authorization": apiKey,
    "Content-Type": "application/json",
    "Accept": "application/json",
    "X-Requested-With": "XMLHttpRequest",
});

// 封装通用请求函数,减少重复代码
async function fetchEndpoint(url) {
    const response = await fetch(url, {
        method: 'GET',
        headers: requestHeaders
    });
    return response.json();
}

async function getData() {
    const endpoints = [
        "https://api.pathfinder2.fr/v1/pf2/action",
        "https://api.pathfinder2.fr/v1/pf2/ancestry",
        "https://api.pathfinder2.fr/v1/pf2/ancestryFeature",
        "https://api.pathfinder2.fr/v1/pf2/archetype",
        "https://api.pathfinder2.fr/v1/pf2/background",
        "https://api.pathfinder2.fr/v1/pf2/class",
        "https://api.pathfinder2.fr/v1/pf2/classFeature",
        "https://api.pathfinder2.fr/v1/pf2/deity",
        "https://api.pathfinder2.fr/v1/pf2/equipment",
        "https://api.pathfinder2.fr/v1/pf2/feat",
        "https://api.pathfinder2.fr/v1/pf2/spell"
    ];

    const allData = await Promise.all(endpoints.map(url => fetchEndpoint(url)));
    
    // 按顺序输出每个接口的数据,只输出一次
    endpoints.forEach((url, index) => {
        console.log(`=== ${url.split('/').pop()} 数据 ===`);
        console.log(allData[index]);
    });

    return allData;
}

// 确保只执行一次
if (!window.pathfinderDataFetched) {
    getData();
    window.pathfinderDataFetched = true;
}

关键优化点

  • 抽离复用requestHeaders,彻底遵循DRY原则
  • 使用Promise.all并行发起请求,比串行请求效率高很多
  • 避免嵌套循环导致的重复请求,每个子endpoint只请求一次
  • 给输出添加标识,方便区分不同接口的数据
  • 确保请求函数只执行一次,解决手动请求时的残留重复问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:46:06