Express中间件,next和Promises [英] Express middleware, next and Promises

查看:39
本文介绍了Express中间件,next和Promises的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个非常简单的带有处理程序的Express路由器:

There is very simple Express router with handler:

router.get('/users/:userId/roles/:roleId', function(req, res, next){
    const roleId = req.params.roleId;
    res.rest.resource = UserModel.findOne({ _id: req.params.userId}).exec().then(function(usr) {
        console.log(req.params.roleId); // => undefined
        console.log(roleId);            // => okay here
        const result = usr.roles.find( role => String(role._id) === String(roleId));
        return result;
    });
    next();
});

如所见,访问promise中的 req.params.roleId 会返回 undefined .这仅在 next()调用外部promise的 then 的情况下才适用.

As it seen accessing req.params.roleId within promise returnes undefined. This is true only for cases when next() called outside promise's then.

我对异步和promise没问题,并且了解到 next()将在 then 中的处理程序之前被调用.但是 req.params.roleId 会发生什么?为什么会在何处发生突变? next()调用的中间件是否变得相同但 req 却被突变了?

I'm okay with asyncing and promises and understand that next() will be called before handler in then. But what happening with req.params.roleId? Why and where it mutates? Does middleware called by next() gets same but mutated req?

注意:稍后调用的中间件使用 res.rest.resource 来建立正确的类似REST的响应.

Note: res.rest.resource used by middleware called later to build right REST-like response.

推荐答案

代码本身在执行过程中是不确定的.

The code as it is is kind of indeterministic in its execution.

某事使 next()处理程序中的角色ID发生突变,并且由于 findOne()最终需要花一些时间才能分配给 then 处理程序,该突变已经发生.

Something mutates the role ID in the next() handler, and since it takes a while for findOne() to eventually dispatch to the then handler, that mutation has already happened.

在不知道您的应用程序更多详细信息的情况下,看来这可能是正确的实现.

Without knowing further details of your app, it looks like this might be the correct implementation.

router.get('/users/:userId/roles/:roleId', function(req, res, next) {
    const roleId = req.params.roleId;
    UserModel.findOne({ _id: req.params.userId}).exec().then((usr) => {
        const result = usr.roles.find(role => String(role._id) === String(roleId));
        res.rest.resource = result;
        next(); // <-- only dispatch to next after we find the resource result
    });
});

我挖得更深一些.看到这个小例子应用程序:

I dug a little deeper. See this little example app:

var express = require('express');
var app = express();

app.use(function (req, res, next) {
    var v = 0 | +new Date();
    console.log("middleware 1 setting foos to ", v);
    req.params.foo = v;
    req.foo = v;
    next();
});

app.use(function (req, res, next) {
    console.log("middleware 2 reading foos and starting timer:", req.params.foo, req.foo);
    setTimeout(function() {
        console.log("middleware 2: foos are now", req.params.foo, req.foo);
    }, 1000);
    next();
});

app.get("/", function(req, res) {
    res.send("params = " + JSON.stringify(req.params) + " and foo = " + req.foo);
});

app.listen(3000);

请求的输出是

middleware 1 setting foos to  -902674369
middleware 2 reading foos and starting timer: undefined -902674369
middleware 2: foos are now undefined -902674369
middleware 1 setting foos to  -902673113
middleware 2 reading foos and starting timer: undefined -902673113
middleware 2: foos are now undefined -902673113

,浏览器输出为 params = {}和foo = -902673113 ,因此事实证明您不允许触摸 req.params ,但是您可以将其他任何属性添加到 req 对象中,它们将正常运行.

and the browser output is params = {} and foo = -902673113, so it turns out that you are not allowed to touch req.params, but you can add any other properties to the req object and they will travel along fine.

这似乎是因为路由匹配层在每个步骤上都重写了 params .

This seems to be because of the route matching layer rewriting params on each step.

这篇关于Express中间件,next和Promises的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆