如何为Binance API的v3/ticker接口添加返回限制实现分页加载?
解决Binance API返回数据过大的分页加载问题
一、处理/api/v3/ticker/price接口
该接口没有直接的分页参数,但可以通过symbols参数指定要获取的交易对,从而实现分批加载,大幅减少响应体积:
实现步骤
- 先调用
/api/v3/exchangeInfo获取全量交易对信息,过滤出以USDT结尾的交易对列表。 - 对列表做分页管理,每次取20个交易对,通过
symbols参数传入接口,仅返回目标数据。 - 点击「加载更多」时,取下一批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的交易对开始返回数据,用于分页续接。
实现思路
- 首次请求时,传入
limit=20,获取前20条数据,记录最后一条的id。 - 点击「加载更多」时,传入
limit=20和fromId=上一页最后一条id,获取下一页数据。 - 若只需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
相关产品推荐
相关产品推荐

