0

I made an api like below.
I think it works asyncrously well without doubt.

exports.query = async(req, res) => {
   try{
      const result = await user.findOne({})
      res.send(result);
   } catch(error) {
      res.send(error)
   }
}

But when I try this like below, I am not sure it works asyncrously or not.

exports.query = async(req, res) => {
   try{
      user.findOne({})
         .then(async(result) =>{
               order.findOne({id: result.id})
         .catch(e => res.send(e)
   } catch(error) {
      res.send(error)
   }
}

I have to attach 'await' in front of user.findOne({}) like below?

exports.query = async(req, res) => {
       try{
          await user.findOne({}) 
             .then(async(result) =>{

Or it doesn't matter? That is, it works same asycrously, even though I don't write await in front to user.findOne using 'then'?

thank you so much for reading.

6
  • 1
    You have to use await to suspend the execution of the async function pending on the promise returned by your chain. Your second example will not work, and additionally it contains a syntax error. Commented Oct 1, 2019 at 3:24
  • 1
    Either use then to chain each of the async functions or use async/await combination to run the async code await user.findOne({}); and so on with a try/catch to handle errors. And don't mix these patterns altogether. Commented Oct 1, 2019 at 3:30
  • Patrick Roberts / thank you so much for your reply. I figured out a syntax error. And I have a question. If I don't write await even though I write async, does it works well without problem using .then of promise? Commented Oct 1, 2019 at 3:33
  • ambianBeing If i miss altogether, what happens? doesnt it work asyncrously? Commented Oct 1, 2019 at 3:34
  • 2
    If you have an async function but don't await or return a Promise, the Promise returned by the function will resolve immediately, which is usually not desirable - generally, it's best to return a Promise that resolves when the function is done with all of its work Commented Oct 1, 2019 at 3:41

2 Answers 2

1

Generally, inside a single block, you should either use await, or use .then, but not both - similarly, using Promise.prototype.catch is really weird in combination with try/catch where you can already await.

For your exports.query to resolve once the second findOne finishes, await or return both Promises, and connect the inner findOne connected to the outer Promise chain. Consider something like this instead:

exports.query = async (req, res) => {
  try {
    const userResult = await user.findOne({});
    const orderResult = await userResult.findOne({ id: userResult.id });
    // do something with orderResult
  } catch (error) {
    res.send(error)
  }
}

If you use .then and catch without await, then it would look like:

exports.query = (req, res) => {
  return user.findOne({})
    .then((result) => {
      return order.findOne({
          id: result.id
        })
        .then((orderResult) => {
          // do something with orderResult
        })
        .catch(e => res.send(e))
    });
}

With the code in the second snippet in your question, your try/catch block will never do anything useful, because any problem will trigger the .catch method, and because the Promise isn't being awaited. Better not to mix the two styles - either pick await and try/catchor .then and .catch, but not both, else the control flow may become difficult to make sense of.

Sign up to request clarification or add additional context in comments.

1 Comment

Either userResult or result. Also your second example doesn't need to nest the chain.
0

First of all, async-await can be used in functions which returns a promise. Why we have to use await instead of then. await process the code asynchronously by making the execution feel like synchronous.

In your first example, everything works fine as expected. But in the second one, you need to await the findOne query. Here the fineOne will work asynchronously

exports.query = async(req, res) => {
   try{
      user.findOne({})
         .then(async(result) =>{
              let orderResult = await order.findOne({id: result.id})
         .catch(e => res.send(e)
   } catch(error) {
      res.send(error)
   }
}

which can be again simplified to

exports.query = async(req, res) => {
   try{
      let result = await user.findOne({});
      let orderResult  = order.findOne({id: result.id});

   } catch(error) {
      res.send(error)
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.