如何在Node.js服务器高效加载Steam库存及物品价格?
优化Steam库存加载与价格获取的实践方案
针对你遇到的多请求限流、数据加载不完整的问题,结合Node.js服务端特性,给出以下落地解决方案:
一、解决多请求问题:后端代理+请求并发控制
前端直接发起大量XHR请求会触发浏览器并发限制,还容易触发Steam API的限流机制。正确做法是把请求逻辑移到Node.js后端统一处理:
- 后端先调用库存API获取物品列表,提取所有
market_hash_name - 对价格API请求做并发控制,比如用
p-limit库限制同时发起的请求数(建议一次最多5个),避免触发Steam的反爬或限流 - 后端整合库存数据与批量获取的价格数据后,一次性返回给前端,前端仅需一次请求即可拿到所有内容
示例Node.js代码:
const fetch = require('node-fetch'); const pLimit = require('p-limit'); // 限制并发请求数为5 const limit = pLimit(5); async function getInventoryWithPrices(steamId) { // 1. 获取用户库存数据 const inventoryRes = await fetch(`https://steamcommunity.com/profiles/${steamId}/inventory/json/730/2`); const inventoryData = await inventoryRes.json(); const itemHashNames = Object.values(inventoryData.rgDescriptions).map(item => item.market_hash_name); // 2. 批量并发获取物品价格 const pricePromises = itemHashNames.map(hashName => limit(async () => { const encodedHash = encodeURIComponent(hashName); const priceRes = await fetch(`https://steamcommunity.com/market/priceoverview/?currency=1&appid=730&market_hash_name=${encodedHash}`); return { hashName, priceData: await priceRes.json() }; }) ); const priceResults = await Promise.all(pricePromises); // 3. 整合库存与价格数据 return inventoryData.rgDescriptions.map(item => ({ ...item, price: priceResults.find(res => res.hashName === item.market_hash_name)?.priceData })); }
二、库存数据的缓存策略:按需缓存+增量更新
完全存储玩家库存并非必须,但合理缓存可减少重复请求:
- 设置缓存有效期:给库存数据设置短缓存(比如10分钟),因为Steam库存不会频繁变动
- 触发缓存更新:用户主动刷新时,先返回缓存数据,同时后台异步拉取最新库存;或缓存过期时自动重新获取
- 处理库存变更:Steam未提供库存变更Webhook,采用"用户触发+缓存过期"的机制即可,既能保证数据新鲜度,又能避免不必要的请求
三、价格数据的持久化:数据库存储+定时更新
将价格存储到数据库是提升获取效率的核心:
- 初始化存储:首次获取某物品价格时,将
market_hash_name、lowest_price、update_time等字段存入数据库(如MySQL、MongoDB) - 定时批量更新:用
node-schedule等工具设置定时任务,每天或每几小时批量更新数据库中物品的价格,减少对Steam API的依赖 - 优先查询数据库:需要物品价格时,先从数据库读取;仅当数据过期或不存在时,再调用Steam API获取并同步到数据库
内容的提问来源于stack exchange,提问作者mathematician256
相关产品推荐
相关产品推荐

