我正在使用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)
返回then
和catch
,并且发生的情况相同。
出了什么问题?
非常感谢,欢呼声
答案 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
方法中reject
或Request.create
s内的任何内容都会被捕获。有关如何从async
函数或Promise
抛出的错误不需要直接捕获它们的位置,请参阅https://repl.it/LtLo/3。