我的作业项目的异步 /等待问题:股票价格检查器



如果我在应用程序中输入库存" GOOG",则日志为:

responseStock = 
stockPrice = 1193.9900
updateStockPrice was a success
[ { stock: 'GOOG', price: '1193.9900', likes: 0 } ]

我已经阅读了许多有关async/等待(和承诺(的文章,包括在stackoverflow.com上,并在freecodecamp论坛上询问了这个问题,但没有得到回应或能够弄清楚它。我尝试了很多代码的变体,并且无法解决异步问题。我所处的位置是在所有功能上都在等待/异步。

app.route('/api/stock-prices')
    .get(function (req, res){
    var stock1 = req.query.stock1.toUpperCase();
    var stock2; //if stock2 compare stock prices
    if (req.query.stock2) { stock2 = req.query.stock2.toUpperCase();}
    var like = req.query.like ? 1 : 0;
    //console.log("like " + like)
    var ip = like ? req.ip : null;
    //console.log("ip is " + ip);
    var stockPrice;
    var responseStock = [];
    var sendResponse = async (response) => {
      if (response.lenght > 1) { //user entered 2 stocks to compare
        var likes0 = response[0].likes - response[1].likes; //compare relative likes
        var likes1 = response[1].likes - response[0].likes;
        await res.json({"stockData": [{"stock": response[0].stock, "price": response[0].price, "rel_likes": likes0},
                               {"stock": response[1].stock, "price": response[1].price, "rel_likes": likes1}]});
      } else {
        console.log("responseStock = " + response);
        await res.json({"stockData": response});
      };
    };
    var addNewStock = async (stock) => {
      var newStock = await new Stock({stock: stock, price: stockPrice, likes: like});
      console.log(newStock);
      newStock.save( (err, doc) => {
        if (err) { console.log(err); }
        else if (!doc) { console.log("addNewStock failed")} 
        else {
          console.log("addNewStock was a success"); 
          responseStock.push({"stock": doc.stock, "price": doc.price, "likes": doc.likes});
          console.log(responseStock);
        }
      });
    };
    var updateStockPriceAndLikes = async (stock) => {
      await Stock.findOneAndUpdate({stock: stock}, {price: stockPrice, $inc: {likes: like}, $push: {ip: ip}},
                             {new: true}, function(err, doc) {
        if (err) { console.log(err); }
        else if (!doc) { console.log("updateStockPriceAndLikes failed"); }
        else { 
          console.log("updateStockPriceAndLikes was a success"); 
          responseStock.push({"stock": doc.stock, "price": doc.price, "likes": doc.likes});
          console.log(responseStock);
        }
      })
    };
    var updateStockPrice = async (stock) => {
      console.log("stockPrice = " + stockPrice)
      await Stock.findOneAndUpdate({stock: stock}, {price: stockPrice},
                             {new: true}, async function(err, doc) {
        if (err) { console.log(err); }
        else if (!doc) { console.log("updateStockPrice failed"); }
        else { 
          console.log("updateStockPrice was a success");
          responseStock.push({"stock": doc.stock, "price": doc.price, "likes": doc.likes});
          console.log(responseStock);
        }
      })
    };
    var handleStock = async (stock) => {
      if (stock) {
       if (ip) {   // like is checked
       await Stock.findOne({stock: stock}, async function(err, doc) {
          if (err) { console.log(err); }
          else if (!doc) { 
           await  addNewStock(stock); //not in db, add new
          } else if (doc.ip.indexOf(ip) < 0) {  //ip not found
            await updateStockPriceAndLikes(stock);   //and push ip to db
          } else {
            await updateStockPrice(stock);
          }
        })
       } else if (!ip) {   //like is not checked
        await Stock.findOne({stock: stock}, async function(err, doc) {
          if (err) { console.log(err); }
          else if (!doc) {
            await addNewStock(stock);
          } else {
            await updateStockPrice(stock);
          }
        });
      }
    };
  };
    var getStockPrice = async (stock) => {  
      var url = "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol="
                + stock + "&apikey=" + process.env.ALPHA_API_KEY;
        await request(url, {json: true}, async function(err, resp, body) {
        if (err) { console.log(err); }
          else if (!body["Global Quote"]["05. price"]) {
            await res.send("please enter a valid stock");
          }
        else {
          //console.log("stockPrice = " + body["Global Quote"]["05. price"]); //correctly logs stock price
          stockPrice = body["Global Quote"]["05. price"];
          await handleStock(stock);
        } 
      })
    };
    var begin = async () => {  
      await getStockPrice(stock1);
      if (stock2) {
        await getStockPrice(stock2);
      }  
      await sendResponse(responseStock);
    };
    begin();
    /*responseStock = [ { stock: 'GOOG', price: '1250.4100', likes: 0 },
  { stock: 'MSFT', price: '141.3400', likes: 0 } ]*/

    });

我希望日志

stockPrice = 1193.9900
updateStockPrice was a success
[ { stock: 'GOOG', price: '1193.9900', likes: 0 } ]
responseStock = [{ stock: 'GOOG', price: '1193.9900', likes: 0 }]

所以,看来我有一个异步问题,我不知道。

as @jfriend00在评论中提到, await将无法在不返回承诺的函数上使用。因此,我需要在我必须更改以返回诺言的情况下使用await的功能。

所以,例如,这不起作用:

var getStockPrice = (stock) => {  
  //request data from API
};
var begin = async () => {  
  await getStockPrice(stock1);
  if (stock2) { await getStockPrice(stock2); }  
  sendResponse(responseStock);
};
begin();

但这确实有效:

var getStockPrice = (stock) => {  
    return new Promise( (resolve, reject) => { 
      //Request data from API
      resolve();
    })   
};
var begin = async () => {  
  await getStockPrice(stock1);
  if (stock2) { await getStockPrice(stock2); }  
  sendResponse(responseStock);
};
begin();

最新更新