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

如何在现有代码中获取API全部19页数据而非仅第一页?

批量获取API多页数据的解决方案

下面的改动几乎不会影响你已有的功能,仅新增多页请求逻辑并替换原有单页请求部分:

1. 新增批量请求函数

先加一个独立函数来处理所有页面的请求,和原有代码完全解耦:

// 批量获取所有页面的鸟类记录
async function fetchAllBirdRecordings() {
    const baseUrl = "https://xeno-canto.org/api/2/recordings?query=cnt:belgium";
    // 先请求第一页拿总页数(如果确定是19页,直接写const totalPages = 19也行)
    const firstPageResponse = await fetch(baseUrl);
    const firstPageData = await firstPageResponse.json();
    const totalPages = firstPageData.numPages;

    // 生成所有页面的请求任务
    const pagePromises = [];
    for (let page = 1; page <= totalPages; page++) {
        pagePromises.push(
            fetch(`${baseUrl}&page=${page}`).then(res => res.json())
        );
    }

    // 等所有请求完成,合并所有记录
    const allPagesData = await Promise.all(pagePromises);
    return allPagesData.flatMap(pageData => pageData.recordings);
}

2. 修改init里的数据获取逻辑

把原来的单页fetch换成调用上面的新函数,原有数据处理、渲染逻辑完全保留:

function init() {
    // 替换原有的单页请求代码
    fetchAllBirdRecordings()
        .then(function (allRecordings) {
            // 复用你原来的遍历逻辑,现在处理所有页面的记录
            allRecordings.forEach(function (recording) {
                const bird = new Bird(recording.date, recording.lat, recording.lng, recording.en, recording.file);
                birdList.push(bird);
                render(bird.HTMLstring);
            });
        })
        .then(function () {
            sorting();
            searching();
        })
        .catch(function (error) {
            console.error("获取数据失败:", error);
        });

    // 地图初始化代码完全不动
    map = new maptalks.Map("map", {
        center: [4.400528, 50.499861],
        zoom: 8,
        baseLayer: new maptalks.TileLayer("base", {
            urlTemplate: "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
            subdomains: ["a", "b", "c", "d"],
            attribution: '&copy; &lt;a href="http://www.osm.org/copyright"&gt;OSM&lt;/a&gt; contributors, ' + '&amp;copy; &lt;a href="https://carto.com/attributions"&gt;CARTO&lt;/a&gt;',
        }),
    });

    layer = new maptalks.VectorLayer("vector").addTo(map);
}

改动优势

  • 原有排序、搜索、地图交互、音频播放等功能一行都不用改,完全复用。
  • 批量请求逻辑封装在独立函数里,即使出问题,也不会影响已有的功能模块。
  • 加了错误捕获,方便排查请求失败的问题。

完整修改后的代码

import Bird from "./Bird.js";

let map;
let layer;
let point;
let birdList = [];
let filteredBirdList = [];
let clickTimeout = null;
const clickDelay = 300;

// 批量获取所有页面的鸟类记录
async function fetchAllBirdRecordings() {
    const baseUrl = "https://xeno-canto.org/api/2/recordings?query=cnt:belgium";
    // 先请求第一页拿总页数(如果确定是19页,直接写const totalPages = 19也行)
    const firstPageResponse = await fetch(baseUrl);
    const firstPageData = await firstPageResponse.json();
    const totalPages = firstPageData.numPages;

    const pagePromises = [];
    for (let page = 1; page <= totalPages; page++) {
        pagePromises.push(
            fetch(`${baseUrl}&page=${page}`).then(res => res.json())
        );
    }

    const allPagesData = await Promise.all(pagePromises);
    return allPagesData.flatMap(pageData => pageData.recordings);
}

function init() {
    // 替换原有的单页请求代码
    fetchAllBirdRecordings()
        .then(function (allRecordings) {
            // 复用你原来的遍历逻辑,现在处理所有页面的记录
            allRecordings.forEach(function (recording) {
                const bird = new Bird(recording.date, recording.lat, recording.lng, recording.en, recording.file);
                birdList.push(bird);
                render(bird.HTMLstring);
            });
        })
        .then(function () {
            sorting();
            searching();
        })
        .catch(function (error) {
            console.error("获取数据失败:", error);
        });

    // 地图初始化代码完全不动
    map = new maptalks.Map("map", {
        center: [4.400528, 50.499861],
        zoom: 8,
        baseLayer: new maptalks.TileLayer("base", {
            urlTemplate: "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
            subdomains: ["a", "b", "c", "d"],
            attribution: '&copy; &lt;a href="http://www.osm.org/copyright"&gt;OSM&lt;/a&gt; contributors, ' + '&amp;copy; &lt;a href="https://carto.com/attributions"&gt;CARTO&lt;/a&gt;',
        }),
    });

    layer = new maptalks.VectorLayer("vector").addTo(map);
}

//FUNCTIES VOOR SORTEREN/FILTEREN

function sorting() {
    const nameButton = document.getElementById("sortByName");
    const dateButton = document.getElementById("sortByDate");
    nameButton.addEventListener("click", function () {
        document.querySelector("#allBirds-list").innerHTML = "";
        birdList.sort(function (birdOne, birdTwo) {
            if (birdOne.name > birdTwo.name) {
                return 1;
            } else {
                return -1;
            }
        });
        birdList.forEach(function (bird) {
            render(bird.HTMLstring);
        });
    });

    dateButton.addEventListener("click", function () {
        document.querySelector("#allBirds-list").innerHTML = "";
        birdList.sort(function (birdOne, birdTwo) {
            if (birdOne.date > birdTwo.date) {
                return 1;
            } else {
                return -1;
            }
        });
        birdList.forEach(function (bird) {
            render(bird.HTMLstring);
        });
    });
}

function searching() {
    const field = document.getElementById("inputField");
    field.addEventListener("input", function (event) {
        const input = event.target.value;

        filteredBirdList = birdList.filter(function (bird) {
            if (input == bird.name) {
                return true;
            }
        });

        document.querySelector("#allBirds-list").innerHTML = "";

        filteredBirdList.forEach(function (bird) {
            render(bird.HTMLstring);
        });

        console.log(filteredBirdList);
    });
}

//FUNCTIES VOOR DE KAART

function addMarker(lat, lng, name) {
    console.log("pin");
    point = new maptalks.Marker([lng, lat], {
        visible: true,
        editable: true,
        cursor: "pointer",
        draggable: false,
        dragShadow: false, // display a shadow during dragging
        drawOnAxis: null, // force dragging stick on a axis, can be: x, y
        symbol: {
            textFaceName: "sans-serif",
            textName: name,
            textFill: "#34495e",
            textHorizontalAlignment: "right",
            textSize: 13,
        },
    });

    point.addTo(layer);
}

//FUNCTIES VOOR DE SELECTIE ACTIE

window.clicking = function (name, rec, lat, lng) {
    if (clickTimeout !== null) {
        clearTimeout(clickTimeout);
        clickTimeout = null;
        doubleClick(name, rec, lat, lng);
    } else {
        clickTimeout = setTimeout(() => {
            singleClick(rec);
            clickTimeout = null;
        }, clickDelay);
    }
};

function singleClick(rec) {
    console.log("enkel");
    playRecording(rec);
}

function doubleClick(name, rec, lat, lng) {
    console.log("dubbel");
    document.querySelector("#myGarden-list").innerHTML += `<button> ${name} </button> </br>`;
    playOnRepeat(rec);
    addMarker(lat, lng, name);
}

//FUNCTIES VOOR HET AFSPELEN VAN HET GELUID

window.playOnRepeat = function (audioFile) {
    const audio = new Audio(audioFile);
    audio.loop = true;
    audio.play();
};

window.playRecording = function (audioFile) {
    //console.log(audioFile);
    const audio = new Audio(audioFile);
    audio.play();
};

//FUNCTIES VOOR HET WEERGEVEN VAN DE KNOPPEN

function render(content) {
    document.querySelector("#allBirds-list").innerHTML += content;
}

init();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:29:53