Home > front end >  await doesn't wait before moving onto next line of code
await doesn't wait before moving onto next line of code

Time:03-12

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

CodePudding user response:

await works very well when you are awaiting a promise that resolves/rejects when the underlying asynchronous operation completes. 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 completed.

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 completes.

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);
}

CodePudding user response:

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. Please upvote another answer.

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.

  • Related