异步函数始终返回undefined

uru*_*ong 4 javascript asynchronous node.js 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)
    }               
}
Run Code Online (Sandbox Code Playgroud)

在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)
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图返回Promise.resolve(response),并Promise.reject(response)thencatch中间件的功能和正在发生的一样.

怎么了?

非常感谢,欢呼

Sve*_*ven 5

您不一定需要在async函数内部与promise进行交互.在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()
  }
}
Run Code Online (Sandbox Code Playgroud)

和你的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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

错误类:

class DatabaseConnectionError extends Error {}
class UnauthorizedError extends Error {}
Run Code Online (Sandbox Code Playgroud)

因为你有try/catch你的HTTP处理程序方法内部的块,任何throwS或reject将在s Request.create方法将在那里抓获.请参阅https://repl.it/LtLo/3,以获得更简洁的示例,说明如何从async函数或Promises中抛出的错误不需要直接捕获它们的位置.