如果我在应用程序中输入库存" 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();