异步函数总是返回未定义

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)
    

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

怎么了?

非常感谢,干杯

【问题讨论】:

你不是awaiting 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 方法中的任何 throws 或 rejects 都将被捕获。请参阅 https://repl.it/LtLo/3 以获取更简洁的示例,了解如何无需在首次调用它们的位置直接捕获从 async 函数或 Promises 引发的错误。

【讨论】:

工作正常,最短,优秀。我对try/catch 感到困惑。非常感谢。 当await Property.findById(id) 失败时,我必须使用trycatch 来抛出错误吗? 不,这将被try/catch 块在exports.create 函数中捕获。 Request.create 方法的整个函数调用链中调用throws 或return Promise.reject() 的任何函数将被@ 内的try/catch 块捕获 987654346@。为了清楚起见,您只需要 try/catch @uruapanmexicansong 我很高兴能帮上忙!我更新了我的答案以显示您如何处理错误。这些是用throw new UnauthorizedError("Unauthorized")return Promise.reject(new UnauthorizedError("Unauthorized")) 抛出的。 哇,我是来找铜的,结果发现了金子。

以上是关于异步函数总是返回未定义的主要内容,如果未能解决你的问题,请参考以下文章

返回未定义的异步函数

如何修复返回“未定义”的异步函数?

异步数据返回中未定义的数据

从异步函数 react-native 获取未定义

从异步函数react-native获取未定义

等待将undefined返回到异步函数(var all_courses未定义)