简体   繁体   中英

Async function always return undefined

im using nodejs 8. I've replaced promise structure code to use async and await.

I have an issue when I need to return an object but await sentence resolve undefined.

This is my controller method:

request.create = async (id, params) => {
    try {
        let request = await new Request(Object.assign(params, { property : id })).save()
        if ('_id' in request) {
            Property.findById(id).then( async (property) => {
                property.requests.push(request._id)
                await property.save()

                let response = {
                    status: 200,
                    message: lang.__('general.success.created','Request')
                }

                return Promise.resolve(response)
            })
        }
    }
    catch (err) {
        let response = {
            status: 400,
            message: lang.__('general.error.fatalError')
        }

        return Promise.reject(response)
    }               
}

In http request function:

exports.create = async (req, res) => {
    try {
        let response = await Request.create(req.params.id, req.body)
        console.log(response)
        res.send(response)
    }

    catch (err) {
        res.status(err.status).send(err)
    }
}

I tried returning Promise.resolve(response) and Promise.reject(response) with then and catch in the middleware function and is occurring the same.

What's wrong?

Thanks a lot, cheers

You don't necessarily need to interact with the promises at all inside an async function. Inside an async function, the regular throw syntax is the same as return Promise.reject() because an async function always returns a Promise . Another thing I noticed with your code is that you're rejecting promises inside a HTTP handler, which will definitely lead to unexpected behavior later on. You should instead handle all errors directly in the handler and act on them accordingly, instead of returning/throwing them.

Your code could be rewritten like so:

request.create = async (id, params) => {
  let request = await new Request(Object.assign(params, { property : id })).save()
  if ('_id' in request) {
    let property = await Property.findById(id)
    property.requests.push(request._id)
    await property.save()
  }
}

And your http handler:

exports.create = async (req, res) => {
  try {
    await Request.create(req.params.id, req.body)
    res.send({
      status: 200,
      message: lang.__('general.success.created','Request')
    })
  } catch (err) {
    switch (err.constructor) {
      case DatabaseConnectionError: // Not connected to database
        return res.sendStatus(500) // Internal server error
      case UnauthorizedError:
        return res.sendStatus(401) // Unauthorized
      case default:
        return res.status(400).send(err) // Generic error
    }
  }
}

Error classes:

class DatabaseConnectionError extends Error {}
class UnauthorizedError extends Error {}

Because you have that try/catch block inside your http handler method, anything that throw s or reject s inside the Request.create method will be caught there. See https://repl.it/LtLo/3 for a more concise example of how errors thrown from async function or Promise s doesn't need to be caught directly where they are first called from.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM