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

如何为Binance API的v3/ticker接口添加返回限制实现分页加载?

解决Binance API返回数据过大的分页加载问题

一、处理/api/v3/ticker/price接口

该接口没有直接的分页参数,但可以通过symbols参数指定要获取的交易对,从而实现分批加载,大幅减少响应体积:

实现步骤

  1. 先调用/api/v3/exchangeInfo获取全量交易对信息,过滤出以USDT结尾的交易对列表。
  2. 对列表做分页管理,每次取20个交易对,通过symbols参数传入接口,仅返回目标数据。
  3. 点击「加载更多」时,取下一批20个交易对,请求后合并到现有数据中。

修改后的代码

import { useState, useEffect } from 'react';

interface BinancePair {
  symbol: string;
  price: string;
}

interface ExchangeInfoSymbol {
  symbol: string;
}

export default function YourComponent() {
  const [usdtPairs, setUsdtPairs] = useState<BinancePair[]>([]);
  const [allUsdtSymbols, setAllUsdtSymbols] = useState<string[]>([]);
  const [currentPage, setCurrentPage] = useState(0);
  const [loading, setLoading] = useState(false);
  const PAGE_SIZE = 20;

  // 初始化获取所有USDT交易对列表
  useEffect(() => {
    const fetchUsdtSymbols = async () => {
      try {
        const response = await fetch('https://api.binance.com/api/v3/exchangeInfo');
        const data = await response.json();
        const usdtSymbols = data.symbols
          .filter((symbol: ExchangeInfoSymbol) => symbol.symbol.endsWith('USDT'))
          .map((symbol: ExchangeInfoSymbol) => symbol.symbol);
        setAllUsdtSymbols(usdtSymbols);
        // 加载第一页数据
        fetchPage(0);
      } catch (error) {
        console.error('获取交易对列表失败:', error);
      }
    };

    fetchUsdtSymbols();
  }, []);

  // 加载指定页的数据
  const fetchPage = async (page: number) => {
    setLoading(true);
    try {
      const startIdx = page * PAGE_SIZE;
      const endIdx = startIdx + PAGE_SIZE;
      const symbolsToFetch = allUsdtSymbols.slice(startIdx, endIdx);

      if (symbolsToFetch.length === 0) {
        setLoading(false);
        return;
      }

      const response = await fetch(
        `https://api.binance.com/api/v3/ticker/price?symbols=${JSON.stringify(symbolsToFetch)}`
      );
      const newData: BinancePair[] = await response.json();

      // 合并数据(第一页直接替换,后续页追加)
      if (page === 0) {
        setUsdtPairs(newData);
      } else {
        setUsdtPairs(prev => [...prev, ...newData]);
      }
      setCurrentPage(page);
    } catch (error) {
      console.error('获取价格数据失败:', error);
    } finally {
      setLoading(false);
    }
  };

  // 加载更多点击事件
  const handleLoadMore = () => {
    const nextPage = currentPage + 1;
    const maxPage = Math.ceil(allUsdtSymbols.length / PAGE_SIZE);
    if (nextPage < maxPage) {
      fetchPage(nextPage);
    }
  };

  return (
    <>
      {usdtPairs.map(pair => (
        <div key={pair.symbol}>
          {pair.symbol}: {pair.price}
        </div>
      ))}
      {loading && <div>加载中...</div>}
      {currentPage < Math.ceil(allUsdtSymbols.length / PAGE_SIZE) - 1 && (
        <button onClick={handleLoadMore} disabled={loading}>
          加载更多
        </button>
      )}
    </>
  );
}

二、处理/api/v3/ticker/24hr接口

该接口原生支持分页参数,可直接实现后端分页:

参数说明

  • limit: 每次返回的条数,最大值为1000,这里设为20。
  • fromId: 从指定ID的交易对开始返回数据,用于分页续接。

实现思路

  1. 首次请求时,传入limit=20,获取前20条数据,记录最后一条的id。
  2. 点击「加载更多」时,传入limit=20和fromId=上一页最后一条id,获取下一页数据。
  3. 若只需USDT交易对,可在请求后过滤,或结合symbols参数批量指定(逻辑同price接口)。

示例代码(分页核心逻辑)

import { useState, useEffect } from 'react';

interface Ticker24hr {
  id: number;
  symbol: string;
  priceChange: string;
  // 其他字段根据业务需求补充
}

export default function Ticker24hrComponent() {
  const [tickerData, setTickerData] = useState<Ticker24hr[]>([]);
  const [lastId, setLastId] = useState<number | null>(null);
  const [loading, setLoading] = useState(false);
  const PAGE_SIZE = 20;

  // 加载第一页数据
  useEffect(() => {
    fetchPage();
  }, []);

  const fetchPage = async (fromId?: number) => {
    setLoading(true);
    try {
      let url = `https://api.binance.com/api/v3/ticker/24hr?limit=${PAGE_SIZE}`;
      if (fromId) {
        url += `&fromId=${fromId}`;
      }

      const response = await fetch(url);
      const newData: Ticker24hr[] = await response.json();

      // 过滤USDT交易对(可选)
      const filteredData = newData.filter(item => item.symbol.endsWith('USDT'));

      setTickerData(prev => [...prev, ...filteredData]);
      // 更新lastId为最后一条数据的id
      if (newData.length > 0) {
        setLastId(newData[newData.length - 1].id);
      }
    } catch (error) {
      console.error('获取24小时行情失败:', error);
    } finally {
      setLoading(false);
    }
  };

  const handleLoadMore = () => {
    if (lastId !== null && !loading) {
      fetchPage(lastId);
    }
  };

  return (
    <>
      {tickerData.map(item => (
        <div key={item.id}>
          {item.symbol}: 涨跌幅 {item.priceChange}
        </div>
      ))}
      {loading && <div>加载中...</div>}
      <button onClick={handleLoadMore} disabled={loading}>
        加载更多
      </button>
    </>
  );
}

注意事项

  • 调用Binance API时需遵守请求频率限制,避免触发限流。
  • 若需要实时更新数据,可结合定时器定期刷新当前页,但需注意分页数据的一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:55:58