所以我有一个post route,它是一个异步等待函数,并且里面有一个reuest,它从api中提取一些数据,我想将该主体的内容保存在请求函数之外的变量中
我曾尝试使用诺言,但我对此并不熟悉。
//@route POST api/portfolio/stock
//@desc Create or update a user's stock portfolio
//@access private
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;
request(`https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${stock}&apikey=${config.get(
"API_KEY")}`, (error, response, body) => {
if (error) console.error(error);
if (response.statusCode !== 200) {
res.status(404).json({msg: 'No stock found'});
}
let content = JSON.parse(body);
let quote = content['Global Quote'];
});
newPortfolio.stocks.stockInfo = quote;
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");
}
}
);
我想使用该请求的正文保存myPortfolio.stocks.stockInfo。
答案 0 :(得分:0)
如何在异步函数中访问外部请求的内容?
你不知道。异步结果仅在异步上下文中可用。对于通过回调返回结果的异步函数,这意味着您在回调内部使用/使用结果。需要访问这些结果的任何代码都将进入回调。在传统的异步Javascript编程中,您只需在回调内继续执行函数代码即可。
幸运的是,promise和async
和await
的发明可以使编码更加简单。对于返回承诺的异步函数(而不是执行回调),可以使用await
来获取结果,并且可以编写看起来更像顺序模型的代码,即使它仍然是异步的。
例如,这是您对函数进行重写的样子,即在我们切换请求承诺库(与请求库相同,但返回一个Promise而不使用回调)之后,我们使用{{1} }上的结果:
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
是一个对象,而不是数组。如果您将相同的变量既用作对象又用作数组,则可能会使阅读代码的人感到困惑。通常,您希望变量(或属性)表现为一个或另一个,而不是两者兼具。