如何在异步函数中访问外部请求的主体?

时间:2019-06-16 01:27:27

标签: javascript node.js api asynchronous request

所以我有一个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。

1 个答案:

答案 0 :(得分:0)

  

如何在异步函数中访问外部请求的内容?

你不知道。异步结果仅在异步上下文中可用。对于通过回调返回结果的异步函数,这意味着您在回调内部使用/使用结果。需要访问这些结果的任何代码都将进入回调。在传统的异步Javascript编程中,您只需在回调内继续执行函数代码即可。

幸运的是,promise和asyncawait的发明可以使编码更加简单。对于返回承诺的异步函数(而不是执行回调),可以使用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是一个对象,而不是数组。如果您将相同的变量既用作对象又用作数组,则可能会使阅读代码的人感到困惑。通常,您希望变量(或属性)表现为一个或另一个,而不是两者兼具。