节点JS异步/等待控制器问题

时间:2019-02-26 18:58:51

标签: javascript node.js express async-await

我正在尝试在Node API控制器中使用异步功能,但收到了来自“错误处理程序”中间件的错误。

  

TypeError:fn不是函数       在评估时(webpack:///./app/middleware/errorHandler.js?:16:21)

它不喜欢从控制器导出的'findAll'函数,为什么这不是函数?我可以正确导出功能吗?我是否正确使用异步/等待?我需要一个polyfill吗?我了解到Node v8支持async / await。我当前正在运行 Node v11.10 Express v4.16.4

这是我的路线文件:

// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const errorHandler = require('../../middleware/errorHandler.js');

module.exports = app => {
    const controller = require('../../controllers/controller.js');

    app.get(`/collection`, verifyToken, errorHandler(controller.findAll));
}

这是我的控制人:

// controller.js
exports.findAll = async (req, res) => {
    const collections = await collection.find().populate('other');
    res.send(collections);
};

这是我的中间件:

// errorHandler.js
module.exports = fn => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我相信,如果我对您的理解正确,那么我就会这样做:

// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const controller = require('../../controllers/controller.js');

module.exports = app => {
  app.get(`/collection`, verifyToken, controller.findAll);
}
// controller.js
exports.findAll = async (req, res, next) => {
  try {
    const collections = await collection.find().populate('other');
    res.send(collections);
  } catch(err) {
    console.log(err); // up to you what to do with the error
    next();
  }
};

答案 1 :(得分:0)

我不确定,但是errorHandler是否期望fn是错误?如果是这样,为什么将其称为传递(要求,下一个要求)?

我使用以下结构:

路由器

// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const controller = require('../../controllers/controller.js');

var router = express.Router()

router.route('/collection').get(
  verifyToken,
  controller.findAll
)
module.exports = router

控制器

// controller.js
const asyncUtil = fn =>
  function asyncUtilWrap(req, res, next, ...args) {
    const fnReturn = fn(req, res, next, ...args)
    return Promise.resolve(fnReturn).catch(next)
  }

module.exports = {
    findAll: asyncUtil(async (req, res, next) => {
        const collections = await collection.find().populate('other'); // you can do try/catch here if you want to handle the error here
        res.send(collections);
};

然后,错误处理程序通常位于app.js的底部(但您可以将其放置在路由器的底部):

// app.js 
app.use(function(err, req, res, next) {
  res.status(err.status || 500)
  res.send(err.message)
})