My code:
async function main(collection, token, symbol) {
await collection.deleteMany({});
const priceHistory = await makePriceHistoryRequest(token, symbol, slow*2);
await insertPriceHistory(collection,priceHistory);
const res = await priceQuote(token,symbol);
await insertQuote(collection,res,symbol);
return await avgFastSlow(fast,slow,collection);
}
My code makes request to 2 endpoints and update MongoDB collection. The last code:
return await avgFastSlow(fast,slow,collection);
takes the updated collection from the two endpoints to calculate fast and slow average. Problem is that it is not waiting before moving onto the this last line of code. Isn't the point of async function to make it "wait?"
Mystified here. Thanks for the help
@ihoryam Thanks for responding. Here is insertQuote
function:
function insertQuote(collection,res,symbol) {
const quote = res[symbol];
const date1 = new Date(quote.quoteTimeInLong).toLocaleDateString();
const record = {
dateInMS: quote.quoteTimeInLong,
dateFormatted: date1,
open: quote.openPrice,
high: quote.highPrice,
low: quote.lowPrice,
close: quote.regularMarketLastPrice,
volume: quote.totalVolume
}
console.log("below is from insertQuote");
console.log(record);
helper(collection,record);
}
async function helper(collection,record) {
await collection.insertOne(record);
}
To further isolate the issue, I added console.log to see if the request is returning updated value, and it is:
console.log("below is from insertQuote");
console.log(record);
So this tells me the problem is with MongoDB isn't updated in time before the code moves onto the calculation part of the code:
async function helper(collection,record) {
await collection.insertOne(record);
}
Any ideas? Thanks
My code:
async function main(collection, token, symbol) {
await collection.deleteMany({});
const priceHistory = await makePriceHistoryRequest(token, symbol, slow*2);
await insertPriceHistory(collection,priceHistory);
const res = await priceQuote(token,symbol);
await insertQuote(collection,res,symbol);
return await avgFastSlow(fast,slow,collection);
}
My code makes request to 2 endpoints and update MongoDB collection. The last code:
return await avgFastSlow(fast,slow,collection);
takes the updated collection from the two endpoints to calculate fast and slow average. Problem is that it is not waiting before moving onto the this last line of code. Isn't the point of async function to make it "wait?"
Mystified here. Thanks for the help
@ihoryam Thanks for responding. Here is insertQuote
function:
function insertQuote(collection,res,symbol) {
const quote = res[symbol];
const date1 = new Date(quote.quoteTimeInLong).toLocaleDateString();
const record = {
dateInMS: quote.quoteTimeInLong,
dateFormatted: date1,
open: quote.openPrice,
high: quote.highPrice,
low: quote.lowPrice,
close: quote.regularMarketLastPrice,
volume: quote.totalVolume
}
console.log("below is from insertQuote");
console.log(record);
helper(collection,record);
}
async function helper(collection,record) {
await collection.insertOne(record);
}
To further isolate the issue, I added console.log to see if the request is returning updated value, and it is:
console.log("below is from insertQuote");
console.log(record);
So this tells me the problem is with MongoDB isn't updated in time before the code moves onto the calculation part of the code:
async function helper(collection,record) {
await collection.insertOne(record);
}
Any ideas? Thanks
Share Improve this question edited Mar 11, 2022 at 23:35 delete_facebook asked Mar 11, 2022 at 22:55 delete_facebookdelete_facebook 471 silver badge7 bronze badges 6-
1
you need to make sure
insertQuote
or any other function that you use withawait
actually returns a Promise – ihoryam Commented Mar 11, 2022 at 23:01 - You'll need to show us the implementations of all those functions where it should wait but doesn't. Do these return promises that are fulfilled at the expected time? – Bergi Commented Mar 11, 2022 at 23:07
- I provided insertQuote details – delete_facebook Commented Mar 11, 2022 at 23:36
-
@delete_facebook Thanks. Well, you're not doing anything with the promise that
helper
returns. You need toawait
(or, in that particular location,return
) thehelper(collection,record);
. And thehelper
function itself seems quite superfluous - why not just callawait collection.insertOne(record);
directly? – Bergi Commented Mar 11, 2022 at 23:41 - 1 Shouldn't insertQuote be an async function and then you await helper ? – Vitor EL Commented Mar 11, 2022 at 23:45
2 Answers
Reset to default 3await
works very well when you are awaiting a promise that resolves/rejects when the underlying asynchronous operation pletes. If you await
something that is not a promise or await
a promise that isn't tied to the underlying asynchronous operation, then it doesn't really do anything useful.
In addition, at the point of the first await
, the parent function will immediately return an unresolved promise and execution will continue after the function call. So, while await
on a promise will suspend the execution of the current function until the promise resolves/rejects, it won't suspend the calling code. The calling code will get a promise back from the async
function and the calling code will have to itself use await
or .then()
to know when the function has actually pleted.
If your await
isn't waiting the way you think it should, then probably you aren't awaiting a promise properly. To help you further with that, we would have to see the code inside the functions that you're awaiting. There is perhaps an implementation error with those functions.
As you can see your insertQuote()
function has no return value. So, when you await insertQuote(...)
, the await
doesn't do anything because you aren't awaiting a promise. You can fix that by changing to this:
function insertQuote(collection,res,symbol) {
const quote = res[symbol];
const date1 = new Date(quote.quoteTimeInLong).toLocaleDateString();
const record = {
dateInMS: quote.quoteTimeInLong,
dateFormatted: date1,
open: quote.openPrice,
high: quote.highPrice,
low: quote.lowPrice,
close: quote.regularMarketLastPrice,
volume: quote.totalVolume
}
console.log("below is from insertQuote");
console.log(record);
return helper(collection,record);
}
function helper(collection,record) {
return collection.insertOne(record);
}
This implementation assumes that collection.insertOne()
returns a promise that resolves/rejects when the underlying database operation pletes.
Now, your insertQuote()
function returns the promise that helper()
returns. Note, there is no reason here for helper()
to be async
because return await collection.insertOne(record)
, does nothing different than return collection.insertOne(record)
. They both return a promise that resolves/rejects the same. If it were inside a try/catch
block, then return await xxx()
could end up the catch
block if it rejects, but you don't have a try/catch
here so return await xxx()
is not appropriate. You can just return the promise directly return xxx()
.
And, if this is the entire code for insertQuote()
, then there's really no reason for helper()
to exist at all. You can just do this:
function insertQuote(collection,res,symbol) {
const quote = res[symbol];
const date1 = new Date(quote.quoteTimeInLong).toLocaleDateString();
const record = {
dateInMS: quote.quoteTimeInLong,
dateFormatted: date1,
open: quote.openPrice,
high: quote.highPrice,
low: quote.lowPrice,
close: quote.regularMarketLastPrice,
volume: quote.totalVolume
}
console.log("below is from insertQuote");
console.log(record);
return collection.insertOne(record);
}
This response has been edited by me because it doesn't answer the question but still sheds some light into the usage of async functions in JS, so I'll leave it up.
return await
is redundant outside of try catch blocks. That's because all async functions return a Promise. So you need to await the function call.
If you do this:
async function main(collection, token, symbol) {
await collection.deleteMany({});
const priceHistory = await makePriceHistoryRequest(token, symbol, slow*2);
await insertPriceHistory(collection,priceHistory);
const res = await priceQuote(token,symbol);
await insertQuote(collection,res,symbol);
return await avgFastSlow(fast,slow,collection);
}
const result = main(collection, token, symbol)
console.log(result);
You'll see that result is actually a promise. Instead, you can do something like this:
async function main(collection, token, symbol) {
await collection.deleteMany({});
const priceHistory = await makePriceHistoryRequest(token, symbol, slow * 2);
await insertPriceHistory(collection, priceHistory);
const res = await priceQuote(token, symbol);
await insertQuote(collection, res, symbol);
return avgFastSlow(fast, slow, collection);
}
(async () => {
const result = await main(collection, token, symbol);
console.log(result);
})();
Now result
should be what you expect.