使用节点7异步/等待来纠正控制器

kev*_*100 8 node.js

让我们看看下面修改过的Restify示例,该示例现在包含Node 7/8s async/await支持.

我对于正确/解决/等等的正确实施有点担忧.我关注的是事件循环中的承诺超过它所需的时间......我知道这不是一个承诺,但是我应该关注这个实现吗?我还没有发现任何问题.

'use strict';

const restify = require('restify');
const User = require('./models/User');

const server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});

server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());

server.get('/echo/:name', async function (req, res, next) {
  try {
    const user = await User.findOne({
      name: req.params.name;
    });
    res.send(user.get({plain: true}));
  } catch (error) {
    console.error(error);
    res.send(500);
  }
  return next();
});

server.listen(8080, function () {
  console.log('%s listening at %s', server.name, server.url);
});
Run Code Online (Sandbox Code Playgroud)

Ant*_*ich 5

async使用函数而不是接受回调的常规函数​​存在问题,因为错误的处理方式不同。

在回调函数(又名“err-backs”)中,无论执行是否成功,都必须调用回调。第一个参数是一个错误对象。

async如果出现任何错误(同步或异步),该函数只是返回一个被拒绝的 Promise。

因此,默认情况下,Express.js/Restify 期望定期返回错误。如果您传递该async函数而失败,Express.js/Restify 将继续等待调用回调,忽略被拒绝的 Promise。它根本不知道返回的承诺并且不处理它。最后,回调根本不会被调用,端点将超时。

所以你将无法正确处理错误。

你可以尝试一下:

server.get('/echo/:name', async function (req, res, next) {
    throw new Error();
});
Run Code Online (Sandbox Code Playgroud)

因此,根据经验,我建议不要混合这些概念,也不要将回调传递到异步函数中。这是一个危险信号。

为了解决这个问题,您需要使用像这样的包装器,例如:

server.get('/echo/:name', async function (req, res, next) {
    throw new Error();
});
Run Code Online (Sandbox Code Playgroud)

您将获得正确的状态代码,并且不会再出现超时。

如果您不想自己包装,还可以使用几个模块: