Вы звоните res.json(array)
до того, как завершится любой из ваших вызовов currentPrice().then(...)
, поэтому массив все еще пуст.
Существует несколько различных способов решения этой проблемы. Вероятно, самое простое - изменить .forEach()
l oop на обычный for
l oop, а затем использовать async/await
для сериализации каждого из ваших вызовов на currentPrice()
:
function currentPrice(ticker) {
const apiURL = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${ticker}&apikey=${API_KEY}`;
return axios.get(apiURL).then(data => {
try {
return data.data["Global Quote"]["05. price"];
}
catch (error) {
console.log(error);
throw error;
}
});
}
app.get("/refresh", redirectLogin, (req, res) => {
const { user } = res.locals;
connection.query(`SELECT * FROM holdings WHERE user_name = '${user.user_name}' AND quantity > 0`, async (err, results) => {
if (err) {
console.log(err);
res.sendStatus(500);
return;
}
try {
const array = [];
for (let holding of results) {
let data = await currentPrice(holding.ticker);
let updatedTicker = {
ticker: holding.ticker,
description: holding.description,
price_acquired: holding.price_acquired,
market_price: data,
delta: parseFloat(this.market_price) - parseFloat(this.price_acquired),
quantity: holding.quantity,
trade_date: holding.date_acquired
}
array.push(updatedTicker);
}
res.json(array);
} catch(e) {
console.log(e);
res.sendStatus(500);
}
});
});
Различные изменения:
- Упрощена функция
currentPrice()
, чтобы просто вернуть топор ios Обещание напрямую - Соответствующее отклонение в
currentPrice()
, если есть ошибка, чтобы вызывающая сторона увидела ошибку . - Добавьте правильную обработку ошибок (отправив ответ об ошибке), если запрос БД не выполнен.
- Переключите
.forEach()
l oop на for
l oop, чтобы мы могли используйте await
для сериализации вызовов на currentPrice()
, чтобы мы могли легче узнать, когда они все будут выполнены. - Добавить обработку ошибок и отправку ответа об ошибке, если
currentPrice()
имеет ошибку. - Вызов
res.json(array)
только после завершения всех теперь сериализованных вызовов await currentPrice()
.
К вашему сведению, полностью завершенное преобразование здесь переключится на mysql2, так что вы можете использовать интерфейс обещания для connection.query()
, а не простой интерфейс обратного вызова, который вы используете сейчас. Это позволит вам упростить обработку ошибок в одном месте.