如何在JavaScript异步场景下存储API响应数据用于后续分析
问题原因
Array.forEach 不支持异步等待逻辑,你传入的async回调函数执行后会返回Promise,但forEach本身不会追踪这些Promise的执行状态,所以外层的await不会生效,代码会直接走到打印data的步骤,此时所有API请求还没有返回,自然只能拿到空数组。
解决方案
把所有异步请求包装为Promise实例存入数组,用Promise.all等待所有请求执行完成后再统一处理数据,修改后的代码如下:
const axios = require('axios'); const { exchanges } = require('./resources/exchanges.json'); const { currencies } = require('./resources/currencies.json'); const buyCurrency = currencies.buy[0]; const poll = async () => { // 收集所有请求的Promise实例 const requestPromises = []; currencies.sell.forEach(sellCurrency => { exchanges.forEach(exchange => { requestPromises.push((async () => { try { const allOtherExchanges = exchanges.filter(x => x !== exchange).map(x => `,${x}`).join(); const response = await axios.get(`https://api.0x.org/swap/v1/quote?buyToken=${buyCurrency}&sellToken=${sellCurrency}&sellAmount=1000000000000000000&excludedSources=0x${allOtherExchanges}`) if (response && response.data.price) { console.log(exchange, sellCurrency, response.data.price) return { exchange, sellCurrency, price: response.data.price }; } return null; } catch { return null; } })()); }); }); // 等待所有请求完成,过滤掉无效的空值 const data = (await Promise.all(requestPromises)).filter(Boolean); console.log(data); // 此处即可正常访问data,执行价差分析等后续逻辑 return data; }; // 如果需要在poll函数外部获取返回的价格数据,按如下方式调用即可: // (async () => { // const priceData = await poll(); // // 后续分析逻辑写在这里 // })() poll()
额外注意事项
- 如果请求量较大,直接用
Promise.all一次性发出所有请求可能会触发API限流,可以引入p-limit等工具控制并发请求量,或者自己实现分批请求逻辑。 - 如果要实现定期轮询,建议在每次poll执行完成后用
setTimeout调度下一次执行,不要使用setInterval,避免上一轮请求还未完成就触发下一轮,导致数据混乱或者请求堆积。
内容的提问来源于stack exchange,提问作者J. Whitehead
相关产品推荐
相关产品推荐

