Как получить доступ к телу запроса снаружи в асинхронной функции?
Нет.Асинхронные результаты доступны только в асинхронном контексте.Для асинхронной функции, которая возвращает результат через обратный вызов, это означает, что вы потребляете / используете результаты ВНУТРИ обратного вызова.Любой код, которому нужен доступ к этим результатам, отправляется в обратном вызове.В традиционном асинхронном программировании Javascript вы просто продолжаете код своей функции внутри обратного вызова.
К счастью, обещания и изобретение async
и await
могут сделать кодирование немного проще.Для асинхронных функций, которые возвращают обещание (вместо обратного вызова), вы можете использовать await
, чтобы получить их результат, и вы можете написать код, который больше похож на последовательную модель, даже если он все еще асинхронный.
Например, вот как может выглядеть переписывание вашей функции, когда мы переключаем библиотеку запроса-обещания (так же, как библиотека запроса, но возвращает обещание вместо использования обратного вызова), а затем мы используем await
для результата:
const rp = require('request-promise');
router.post(
"/stock",
auth,
[
check("symbol", "symbol is require or incorrect.")
.not()
.isEmpty(),
check("qty", "Quantity of the stock purchased is required")
.not()
.isEmpty()
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty) {
return res.status(400).json({
errors: errors.array()
});
}
const {
stock,
qty
} = req.body;
const newPortfolio = {};
newPortfolio.user = req.user.id;
newPortfolio.stocks = [];
if (stock) newPortfolio.stocks.stock = stock;
if (qty) newPortfolio.stocks.qty = qty;
try {
let body = await rp(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${stock}&apikey=${config.get("API_KEY")}`);
let content = JSON.parse(body);
newPortfolio.stocks.stockInfo = content['Global Quote'];
} catch (e) {
console.error(e);
res.status(404).json({
msg: 'No stock found'
});
return;
}
try {
let portfolio = await Portfolio.findOne({
user: user.req.id
});
//update if exists
if (portfolio) {
portfolio = await Portfolio.findOneAndUpdate({
user: user.req.id
}, {
$push: {
stocks: newPortfolio.stocks
}
});
return res.json(portfolio);
}
//create if not found
portfolio = new Portfolio(newPortfolio);
await portfolio.save();
res.json(portfolio);
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
}
);
Примечание: добавление свойств в массив newPortfolio.stocks
довольно необычен.Хотя это технически неправильно, вы обычно объявляете newPortfolio.stocks
объектом, а не массивом, если вы просто собираетесь добавить к нему свойства и не использовать его как настоящий массив.Люди, которые читают ваш код, часто могут сбить с толку, если вы используете ту же переменную, что и для объекта, и для массива.Обычно вы хотите, чтобы переменная (или свойство) велась как одна или другая, а не как обе.