【问题标题】:nodejs express middleware function return valuenodejs express 中间件函数返回值
【发布时间】:2014-07-20 21:09:14
【问题描述】:

我正在使用 NodeJS 和 Express,我有以下路线,中间件功能是 Mobile。如果我不使用 return next();在 isMobile 函数中,应用程序卡住了,因为 NodeJS 没有移动到下一个函数。

但我需要 isMobile 函数返回一个值,以便我可以在 app.get 中进行相应处理。有什么想法吗?

app.get('/', isMobile, function(req, res){
 // do something based on isMobile return value
});



function isMobile(req, res, next) {

    var MobileDetect = require('mobile-detect');
    md = new MobileDetect(req.headers['user-agent']);

    //return md.phone(); // need this value back

    return next();
}

谢谢。

【问题讨论】:

  • 如果 isMobile 功能是您路由的结束,为什么还要添加另一个功能?
  • 我不明白为什么你需要你的下一个函数来返回任何东西。你不能简单地指望它。如果您需要将某些内容传递给下一个函数,请将其放入请求对象中。

标签: node.js express


【解决方案1】:

你有几个选择:

  1. 将值附加到req 对象:

    app.get('/', isMobile, function(req, res){
       // Now in here req.phone is md.phone. You can use it:
       req.phone.makePrankCall();
    });
    
    function isMobile(req, res, next) {
        var MobileDetect = require('mobile-detect');
        md = new MobileDetect(req.headers['user-agent']);
    
        req.phone = md.phone();
        next();// No need to return anything.
    }
    

    这是 express/connect 中间件传递值的数量。比如 bodyParser 将 body 属性附加到请求对象,或者会话中间件将会话属性附加到请求对象。

但请注意,您必须注意没有其他库使用该属性,因此不会发生冲突。

  1. 不要把它做成中间件,直接使用函数即可。如果它不像上面那样异步,并且不会被全局用于所有路由(不会有这样的东西:app.use(isMobile)),这也是一个很好的解决方案:

    app.get('/', function(req, res){
       var phone = isMobile(req);
       phone.makePrankCall();
    });
    
    function isMobile(req) {
        var MobileDetect = require('mobile-detect');
        md = new MobileDetect(req.headers['user-agent']);
    
        return md.phone();
    }
    

如果计算成本很高,并且您可能在多个中间件中使用它,则可以使用 Wea​​kMap(or use a module that does it for you) 对其进行缓存:

    app.get('/', function(req, res){
       var phone = isMobile(req);
       phone.makePrankCall();
    });

    var cache = new WeakMap()

    function isMobile(req) {
        var MobileDetect = require('mobile-detect');

        result = cache.get(req);

        if (result) {
            return result;
        } else {
            md = new MobileDetect(req.headers['user-agent']).phone();
            cache.set(req, md);
            return md;
        }
    }

【讨论】:

  • 您对使用 Wea​​kmap 的建议非常有趣。我猜如果您的中间件处理程序位于另一个文件中,您将无法执行此操作,因为一旦调用 next 就无法将弱映射传回......还是我误解了这一点?
  • @goldmund 我添加了一个例子来说明它是如何实现的。 WeakMap 应该只被中间件函数使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 2015-04-19
  • 2013-09-27
  • 2018-07-04
  • 1970-01-01
  • 2019-07-25
  • 2020-09-16
相关资源
最近更新 更多