如何将Connect中间件组合到一个中间件中?

Eva*_*ahn 5 middleware connect node.js

我有一些中间件,我想要组合成一个中间件.我怎么做?

例如...

// I want to shorten this...
app.use(connect.urlencoded())
app.use(connect.json())

// ...into this:
app.use(combineMiddleware([connect.urlencoded, connect.json]))

// ...without doing this:
app.use(connect.urlencoded()).use(connect.json())
Run Code Online (Sandbox Code Playgroud)

我希望它工作动态-我不想依赖我使用的中间件.

我觉得除了令人困惑的for循环外,还有一个优雅的解决方案.

San*_*tta 15

app.use如果您有路径,Express接受数组:

var middleware = [connect.urlencoded(), connect.json()];
app.use('/', middleware)
Run Code Online (Sandbox Code Playgroud)

但是,如果您需要通用combineMiddleware函数,则可以轻松构建帮助程序而无需任何其他库.这基本上利用了这一事实next只是一个带有可选错误的函数:

/**
 * Combine multiple middleware together.
 *
 * @param {Function[]} mids functions of form:
 *   function(req, res, next) { ... }
 * @return {Function} single combined middleware
 */
function combineMiddleware(mids) {
  return mids.reduce(function(a, b) {
    return function(req, res, next) {
      a(req, res, function(err) {
        if (err) {
          return next(err);
        }
        b(req, res, next);
      });
    };
  });
}
Run Code Online (Sandbox Code Playgroud)


vku*_*kin 6

如果你喜欢花哨的东西,这里有一个可能的解决方案:

var connect = require('connect')
var app = connect()

function compose(middleware) {
  return function (req, res, next) {
    connect.apply(null, middleware.concat(next.bind(null, null))).call(null, req, res)
  }
}

function a (req, res, next) {
  console.log('a')
  next()
}

function b (req, res, next) {
  console.log('b')
  next()
}

app.use(compose([a,b]))

app.use(function (req, res) {
  res.end('Hello!')
})

app.listen(3000)
Run Code Online (Sandbox Code Playgroud)

这是它的作用:compose函数接受中间件数组并返回组合中间件。connect本身基本上是一个中间件作曲家,因此您可以使用所需的中间件创建另一个连接应用程序:connect.apply(null, middleware). Connect app 本身就是一个中间件,唯一的问题是它最终没有next()调用,所以后续的中间件将无法访问。为了解决这个问题,我们需要另一个last中间件,它将调用next: connect.apply(null, middleware.concat(last))。作为最后一个next我们可以使用的唯一调用next.bind(null, null)。最后,我们用req和调用结果函数res