异步函数总是返回未定义
Posted
技术标签:
【中文标题】异步函数总是返回未定义【英文标题】:Async function always return undefined 【发布时间】:2018-03-12 13:30:20 【问题描述】:我使用的是 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)
我尝试在中间件函数中使用then
和catch
返回Promise.resolve(response)
和Promise.reject(response)
,并且发生了同样的情况。
怎么了?
非常感谢,干杯
【问题讨论】:
你不是await
ing Property.findById(id).then(…)
承诺。事实上你可能应该在这里使用then
,但只是const property = await Property.findById(id); …
【参考方案1】:
您根本不需要在 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()
还有你的 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
块,所以 Request.create
方法中的任何 throw
s 或 reject
s 都将被捕获。请参阅 https://repl.it/LtLo/3 以获取更简洁的示例,了解如何无需在首次调用它们的位置直接捕获从 async
函数或 Promise
s 引发的错误。
【讨论】:
工作正常,最短,优秀。我对try/catch
感到困惑。非常感谢。
当await Property.findById(id) 失败时,我必须使用try
和catch
来抛出错误吗?
不,这将被try/catch
块在exports.create
函数中捕获。 在Request.create
方法的整个函数调用链中调用throw
s 或return Promise.reject()
的任何函数将被@ 内的try/catch
块捕获 987654346@。为了清楚起见,您只需要 try/catch
块。
@uruapanmexicansong 我很高兴能帮上忙!我更新了我的答案以显示您如何处理错误。这些是用throw new UnauthorizedError("Unauthorized")
或return Promise.reject(new UnauthorizedError("Unauthorized"))
抛出的。
哇,我是来找铜的,结果发现了金子。以上是关于异步函数总是返回未定义的主要内容,如果未能解决你的问题,请参考以下文章