因此,我目前正在开发一个项目,当用户登陆仪表板页面时,需要计算给定用户的持仓值(value)(股票列表及其金额)。目前,我正在通过 GET 为持有列表中的每一项调用 API,并计算这些股票的当前总值(value)。最后,我得到了股票代码、当前值、金额和总计(金额 * 当前值)。然后我想通过 render() 中的 map 函数向用户显示这些值。
最初,我尝试在渲染中的 map 函数中获取并计算所有这些信息,该函数将迭代馆藏列表。然而,我什至无法让它编译而不遇到关于放置在 JSX 中的 promise 的错误(我正在处理异步)。我意识到我可以简单地计算 componentDidMount() 中的列表,所以我选择了这样做。
不幸的是,尽管这次确实可以编译,但我仍然遇到问题。在 componentDidMount() 中,我执行以下操作:
const holdings = store.getState().mainApp.portfolio.holdings;
var newHoldings = []
holdings.forEach(async element => {
const stock = await axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`);
let stockPrice = stock.data[0].price
let total = +stockPrice * +element.qty;
newHoldings.push({
ticker: element.ticker,
qty: element.qty,
price: stockPrice,
totPrice: total
})
});
this.setState({ activePortfolio: newHoldings })
这是我在渲染函数中所做的事情
{this.state.activePortfolio ?
// CONSOLE LOG HERE OF activePortfolio RETURNS THE CALCULATED LIST
this.state.activePortfolio.map((value) =>
// CONSOLE LOG HERE RETURNS NOTHING
console.log(value)
// <div>
// <p>{value.ticker} <span style={{right: '2vw', float: 'right'}}>{value.qty}x @ ${value.price}/ea</span></p>
// <p style={{float: 'right'}}> $ {value.totPrice}</p>
// </div>
)
:
console.log("ERROR ACTIVE P")
}
目前, map 函数仅记录 activePortfolio 中的每个值,但是当我运行它并且有 Assets 时,它不会记录任何内容。然而,如上所示,它确实记录了列表(如果没有迭代)。有谁知道这是怎么回事?我只是错过了一些小而基本的东西吗?
谢谢大家!
编辑...(根据@zero298的评论)
var promises = holdings.map(element => {
return axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`).then(stock => {
let stockPrice = stock.data[0].price
let total = +stockPrice * +element.qty;
return ({
ticker: element.ticker,
qty: element.qty,
price: stockPrice,
totPrice: total
});
})
})
console.log(Promise.all(promises))
Promise.all(promises).then(res => {
newHoldings = res;
});
所以现在,当我将新的持有设置到 res 时(顺便说一句,res 在记录时正确显示数组值),它仍然无法在 render() 内的 map 函数中记录该值。我在这里做错了什么吗?我对 Promise 还是有点陌生。
编辑 2... 好的!感谢@dave 和@zero298 的帮助。我最终使用了组合解决方案。上述编辑的唯一问题是我没有将 componentDidMount() 设为异步函数,也没有在 Promise.all() 函数上调用 wait 。 (完全没想到你可以用 componentDidMount() 做到这一点!)这是固定的解决方案......
async componentDidMount(){
*... other init code ...*
var promises = holdings.map(element => {
return axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`).then(stock => {
let stockPrice = stock.data[0].price
let total = +stockPrice * +element.qty;
return ({
ticker: element.ticker,
qty: element.qty,
price: stockPrice,
totPrice: total
});
})
})
console.log(Promise.all(promises))
await Promise.all(promises).then(res => {
newHoldings = res;
});
};
非常感谢你们,我真的很感谢你们的帮助!
最佳答案
我想你可能只想这样做:
await Promise.all(promises).then(res => {
newHoldings = res;
});
如果这不起作用,您可以这样做:
for await (const holding of holdings) {
const stock = await axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${holding.ticker}`);
let stockPrice = stock.data[0].price
let total = +stockPrice * +holding.qty;
newHoldings.push({
ticker: holding.ticker,
qty: holding.qty,
price: stockPrice,
totPrice: total
})
};
this.setState({ activePortfolio: newHoldings })
关于javascript - 在 map 函数中异步调用 API (React),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60436930/