Javascript 使用async/await时try/catch中的作用域出现问题

Javascript 使用async/await时try/catch中的作用域出现问题,javascript,node.js,express,mongoose,jestjs,Javascript,Node.js,Express,Mongoose,Jestjs,我的问题是(似乎)当我在下面的函数中输入我的catch块时,事情超出了范围,或者范围被污染了: export const getOne = model => async (req, res, next) => { let id = req.params.id let userId = req.user try { let item = await model.findOne({ _id: id, createdBy: userId }).exec() if

我的问题是(似乎)当我在下面的函数中输入我的
catch
块时,事情超出了范围,或者范围被污染了:

export const getOne = model => async (req, res, next) => {
  let id = req.params.id
  let userId = req.user
  try {
    let item = await model.findOne({ _id: id, createdBy: userId }).exec()
    if (!item) {
      throw new Error('Item not found!')
    } else {
      res.status(200).json({ data: item }) // works perfectly
    }
  } catch (e) {
    res.status(400).json({ error: e }) // TypeError: res.status(...).json is not a function
    // also TypeError: next is not a function
    // next(e)
  }
}
有趣的是,在
catch
块中使用
res.status(…).end()
效果很好,但我无法将任何细节与响应一起发送回来,这让我很烦恼。根据和的快速文档,我应该能够链接
.status()
,这也很有趣,如果事情成功的话,在上面的
try
语句中也可以很好地工作-
res.status(200)。json(…)

另外,我尝试将错误处理抽象到中间件,通过闭包,我仍然可以访问
catch
语句中的
next
,对吗?为什么这不是一个函数

  • 为什么
    res.status(…).json(…)
    可以在我的
    try
    块中工作,但不能在
    catch
    块中工作
  • 为什么
    next
    不再是
    catch
    块中的函数
  • 提前谢谢

    编辑 如果单元测试失败,以下代码将产生上述错误:

    describe('getOne', async () => {
      // this test passes
      test('finds by authenticated user and id', async () => {
        expect.assertions(2)
    
        const user = mongoose.Types.ObjectId()
        const list = await List.create({ name: 'list', createdBy: user })
    
        const req = {
          params: {
            id: list._id
          },
          user: {
            _id: user
          }
        }
    
        const res = {
          status(status) {
            expect(status).toBe(200)
            return this
          },
          json(result) {
            expect(result.data._id.toString()).toBe(list._id.toString())
          }
        }
    
        await getOne(List)(req, res)
      })
      // this test fails
      test('400 if no doc was found', async () => {
        expect.assertions(2)
    
        const user = mongoose.Types.ObjectId()
    
        const req = {
          params: {
            id: mongoose.Types.ObjectId()
          },
          user: {
            _id: user
          }
        }
    
        const res = {
          status(status) {
            expect(status).toBe(400)
            return this
          },
          end() {
            expect(true).toBe(true)
          }
        }
    
        await getOne(List)(req, res)
      })
    })
    
    为什么res.status(…).json(…)在我的try而不是catch块中工作


    似乎您正在传递一个非express对象,该对象在使用单元测试运行时只有
    status
    &
    end
    方法。这就是为什么它找不到感兴趣的
    json
    方法的原因indeed@Arik添加了用于重现这些错误的单元测试代码。@DanStarns,OP添加了通过非express
    res
    object的单元测试。噢,我是个白痴。我明白问题是什么了。测试正在传递我可以在响应对象上运行的特定函数。除了
    .end()
    我想变得太花哨之外,它不希望我做任何事情。德普。非常感谢@Arik!!如果你想写一个快速的答案,我会标为接受。否则我会删除这个问题,谢谢,不知道我怎么会忽略这个!