如何利用Promise.all高效实现基于MongoDB关注列表的CoinMarketCap API数据更新?
你的思路完全站得住脚,而且用Promise.all()来并行处理API请求绝对是提升效率的正确选择!我帮你把具体落地步骤拆解得明明白白,再附个实用的代码示例参考:
具体实现步骤
- 第一步:提取并整理加密货币标识
先从MongoDB中查询所有用户的watchlists数据,把列表里的加密货币ID(比如bitcoin这种slug)提取出来,记得做去重处理——如果多个用户关注同一个币种,重复请求API纯粹是浪费资源,还容易触发平台限流。 - 第二步:适配API请求规则
确认CoinMarketCap API的批量请求限制,比如它的/v1/cryptocurrency/quotes/latest接口支持用逗号分隔多个slug或数字ID,一次请求最多可传入一定数量的币种(比如100个)。如果你的去重后币种数量超过这个限制,就把它们分成若干批次。 - 第三步:用Promise.all()并行发起请求
把每个批次的请求封装成Promise,放入一个数组中,然后用Promise.all()等待所有请求完成。这种并行请求的方式比串行请求快好几倍,能大幅提升处理效率。 - 第四步:关联数据并返回结果
把API返回的所有最新数据合并成一个映射表,再逐个匹配到每个用户的watchlist中,最终返回带最新行情数据的用户关注列表。
代码示例(Node.js环境)
// 假设你已经实现了MongoDB查询函数getAllUserWatchlists async function fetchLatestCryptoData() { try { // 提取所有用户关注的币种slug并去重 const userWatchlists = await getAllUserWatchlists(); const allCryptoSlugs = userWatchlists.flatMap(watchlist => watchlist.cryptos); const uniqueSlugs = [...new Set(allCryptoSlugs)]; // 分批处理(适配API单次请求数量限制) const batchSize = 100; const batches = []; for (let i = 0; i < uniqueSlugs.length; i += batchSize) { batches.push(uniqueSlugs.slice(i, i + batchSize)); } // 并行发起API请求 const apiKey = '你的CoinMarketCap API密钥'; const fetchPromises = batches.map(batch => { const slugsStr = batch.join(','); return fetch(`https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?slug=${slugsStr}`, { headers: { 'X-CMC_PRO_API_KEY': apiKey } }).then(res => res.json()); }); const apiResults = await Promise.all(fetchPromises); // 合并API结果为映射表 const cryptoDataMap = {}; apiResults.forEach(result => { Object.assign(cryptoDataMap, result.data); }); // 关联数据到用户关注列表 const userWatchlistsWithData = userWatchlists.map(watchlist => ({ ...watchlist, cryptos: watchlist.cryptos.map(slug => ({ slug, latestData: cryptoDataMap[slug] || { error: '币种数据未找到' } })) })); return userWatchlistsWithData; } catch (error) { console.error('获取加密货币行情数据失败:', error); throw error; } }
额外注意事项
- 记得处理API限流:CoinMarketCap有请求频次限制,若批量请求过多,可加入简单的延时或重试机制。
- 容错处理:如果某个币种的API请求失败,要确保不影响整体流程,给对应位置返回错误提示即可。
- 若MongoDB中存储的是CoinMarketCap数字ID而非slug,只需把请求参数改成
id=${idsStr}即可,逻辑完全一致。
内容的提问来源于stack exchange,提问作者jpatel701
相关产品推荐
相关产品推荐

