异步函数始终返回undefined

时间:2017-10-01 04:29:47

标签: javascript node.js asynchronous promise async-await

我正在使用nodejs 8.我已经取代了promise结构代码以使用async和await。

当我需要返回一个对象但等待句子解析未定义时,我遇到了一个问题。

这是我的控制器方法:

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

在http请求函数中:

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

我尝试在中间件功能中使用Promise.resolve(response)Promise.reject(response)返回thencatch,并且发生的情况相同。

出了什么问题?

非常感谢,欢呼声

1 个答案:

答案 0 :(得分:5)

您不一定需要在async函数内与promises交互。在async函数中,常规throw语法与return Promise.reject()相同,因为async函数始终返回Promise。我注意到你的代码的另一件事是你在HTTP处理程序中拒绝承诺,这肯定会导致以后的意外行为。您应该直接在处理程序中处理所有错误并相应地对其进行操作,而不是返回/抛出它们。

您的代码可以像这样重写:

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

你的http处理程序:

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

错误类:

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

因为您的http处理程序方法中有try/catch块,所以throw方法中rejectRequest.create s内的任何内容都会被捕获。有关如何从async函数或Promise抛出的错误不需要直接捕获它们的位置,请参阅https://repl.it/LtLo/3