Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Express-在中间件功能之间传递数据的更好模式_Javascript_Node.js_Express - Fatal编程技术网

Javascript Express-在中间件功能之间传递数据的更好模式

Javascript Express-在中间件功能之间传递数据的更好模式,javascript,node.js,express,Javascript,Node.js,Express,我刚刚向Express提出了这个问题,我对StackOverflow的想法很感兴趣: 我的问题是,为什么Express不允许开发人员在中间件功能之间直接传递数据,并且基本上迫使您将临时数据分配给请求对象,我一直认为这是一个相当尴尬的分配 更具体地说: 在中间件功能之间传递数据通常需要这样做 req.specialData = {} next(); 然而,如果这是可能的话,它可能会更容易和更有效(!) next(null,data); 或 //现在,调用上面的函数 mySpecialMidd

我刚刚向Express提出了这个问题,我对StackOverflow的想法很感兴趣:

我的问题是,为什么Express不允许开发人员在中间件功能之间直接传递数据,并且基本上迫使您将临时数据分配给请求对象,我一直认为这是一个相当尴尬的分配

更具体地说:

在中间件功能之间传递数据通常需要这样做

req.specialData = {}
next();
然而,如果这是可能的话,它可能会更容易和更有效(!)

next(null,data);

//现在,调用上面的函数

mySpecialMiddleWare(req,res,next, {some:data});
问题是Express使用了一种我认为是愚蠢的方法,通过检查function.length>3或function.length==4来确定调用是针对普通中间件函数还是针对下一个错误第一个中间件函数

我说的有可能有意义吗

允许通过中间件函数直接传递数据,而不是笨拙地将数据分配给req,不是更好/更容易/更快/更强吗

也许Express已经有了这种能力,而我只是误报了

我的问题是,为什么Express不允许开发人员在中间件功能之间直接传递数据,并且基本上迫使您将临时数据分配给请求对象,我一直认为这是一个相当尴尬的分配

因此,我认为API是鼓励大多数中间件模块化、可重用和松散耦合的方式。这意味着用户通常应该做一些事情,而不必太担心其他中间件可能在他们之前或之后运行。为了实现这一点并创建一个松散兼容中间件功能的生态系统,express将API保持为相当通用的。这有优点也有缺点。但作为对第一个问题的直接回答,我想说的是保持接口简单、一致和灵活,并尽量避免严格的顺序依赖关系

与您的情况一样,中间件之间可能存在隐式依赖关系。另一个常见的例子是,会话中间件通常有一个隐式依赖项,cookie中间件在它之前运行。如果这些都是隐式的,可能会导致错误和不必要的故障排除。另一方面,它使应用程序开发人员能够更轻松地混合和匹配可能不知道彼此的中间件

事后看来,我想我和一些express维护人员都会同意,出于语义API的原因使用函数arity(预期参数的数量)对TJ来说是一个奇怪而糟糕的选择。我认为,如果要重写项目,将为错误处理定义一个更明确的API

允许通过中间件函数直接传递数据,而不是笨拙地将数据分配给req,不是更好/更容易/更快/更强吗

更好-这是非常有争议的和基于意见的。它的简单性有很多值得一提的地方,证据就是巨大的生态系统和用途。有可用的替代方案,如HAPI、REST等,尽管如此,您可能会考虑它们。

更容易——可能不会。这很简单

更快-可能没有任何意义。不确定为什么您认为您的版本会更快,但最好在您做出此类声明时提供度量标准


更强-如果“更强”的意思是更明确,这可能是真的,但有些人仍然喜欢JavaScript,尽管从Haskell到TypeScript都存在,而且从某种意义上说肯定是“更强”的。

但是,Express的功能可能有优势,值得注意的是,Express允许使用res.locals在中间件之间传递数据。话虽如此,你的问题激励我建立这个图书馆。 使用它,您将能够轻松地在中间件之间传递数据,而无需使用请求或响应对象

您可以使用常规javascript函数,例如函数(varInResLocals、varInReqParams、callback),而不是express中间件签名

下面是一个工作示例

 var express = require('express');
 var ExpressPlus = require('expressjs-plus').ExpressPlus;
 var app = express();
 // simple handler example
 var userHandler = function(param, paramsArray, req, res){
    if(param !== 'user') return false;
    paramsArray.push("USER WAS FOUND!");
    return true;
};

 // this handler allows you to pass res.locals properties between your middlewares seemingly,
 // it the parameter was found in locals, it attaches it to paramsArray.
 var resLocalsHandler = function(param, paramsArray, req, res){
    if(param in res.locals){
        paramsArray.push(res.locals[param]);
        return true;
    }else return false;
};
 var appPlus = new ExpressPlus(app, [userHandler, resLocalsHandler], []);
 var regularFunction = function(user, id, cb){
    return cb(null, { response: {user: user, id: id}, status: 200, resLocalsVar: "passVar" });
};

 // resLocalsVar was passed in a previous method
 var regularFunction2 = function(resLocalsVar, user, id, cb){
 // now you can have access to it
    console.log(resLocalsVar);
    return cb(null);
};

 // the responder at the end will use res.locals.status and res.locals.response to issue an HTTP response
 app.use(appPlus.GMV(regularFunction), appPlus.GMV(regularFunction2), appPlus.responder);

 // adds error handlers, it will add a default error handler along with the list of error handlers passed
 // in this case, no error handlers were passed
 appPlus.setErrorHandlers();

 app.listen(3001, function(){
    console.log('Listening!');
});    

谢谢你肯定提出了一些好的观点;我的意思是在愚蠢的朋克感官中更快/更强。不过,将这样的临时变量签名到req可能会增加内存?只在函数之间传递变量肯定会占用更少的内存。另外,一种方法是调用一个具有5个或更多参数的中间件函数,这应该绕过错误中间件,只需进入下一个中间件函数-也就是说,如果Express没有从下一次调用中剪裁/截断额外参数。但是不能用next()调用它,必须用中间件(req、res、next、{}、{})调用它。如果中间件模式不合适,就使用好的旧函数。是的,但我只是希望你能调用next(null,{}),那就太好了。Express(如果所有其他的话)可以为您将该对象放在req上,因此上面的调用会将该对象分配给req.foo或其他任何东西…并且如果您可以对req上临时变量的内存增加进行注释…不确定这是否有影响。
 var express = require('express');
 var ExpressPlus = require('expressjs-plus').ExpressPlus;
 var app = express();
 // simple handler example
 var userHandler = function(param, paramsArray, req, res){
    if(param !== 'user') return false;
    paramsArray.push("USER WAS FOUND!");
    return true;
};

 // this handler allows you to pass res.locals properties between your middlewares seemingly,
 // it the parameter was found in locals, it attaches it to paramsArray.
 var resLocalsHandler = function(param, paramsArray, req, res){
    if(param in res.locals){
        paramsArray.push(res.locals[param]);
        return true;
    }else return false;
};
 var appPlus = new ExpressPlus(app, [userHandler, resLocalsHandler], []);
 var regularFunction = function(user, id, cb){
    return cb(null, { response: {user: user, id: id}, status: 200, resLocalsVar: "passVar" });
};

 // resLocalsVar was passed in a previous method
 var regularFunction2 = function(resLocalsVar, user, id, cb){
 // now you can have access to it
    console.log(resLocalsVar);
    return cb(null);
};

 // the responder at the end will use res.locals.status and res.locals.response to issue an HTTP response
 app.use(appPlus.GMV(regularFunction), appPlus.GMV(regularFunction2), appPlus.responder);

 // adds error handlers, it will add a default error handler along with the list of error handlers passed
 // in this case, no error handlers were passed
 appPlus.setErrorHandlers();

 app.listen(3001, function(){
    console.log('Listening!');
});