2013-11-28 3 views
3

У меня есть несколько посредников, которые я хочу объединить в одно промежуточное ПО. Как мне это сделать?Как объединить промежуточное ПО Connect в одно промежуточное ПО?

Например ...

// 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()) 

Я хочу работать динамически - Я не хочу зависеть от которые промежуточного я использую.

Я чувствую, что есть элегантное решение, отличное от запутанной петли for.

ответ

3

Если вы любите модные вещи, вот один из возможных решений:

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) 

Вот что он делает: compose функции принимает массив промежуточного программного обеспечения и возврат в состав промежуточного уровня. connect сам по себе является композитором промежуточного программного обеспечения, поэтому вы можете создать другое приложение для подключения с помощью посредников, которые вы хотите: connect.apply(null, middleware). Приложение Connect является промежуточным программным обеспечением, единственная проблема заключается в том, что в конце концов нет вызова next(), поэтому последующее промежуточное программное обеспечение будет недоступно. Чтобы решить эту проблему, нам понадобится другое промежуточное программное обеспечение last, которое будет называть next: connect.apply(null, middleware.concat(last)). Поскольку последние только звонки next, мы можем использовать next.bind(null, null). Наконец, мы вызываем результирующую функцию с req и res.

+0

Хороший, но я бы утверждать, что это более запутанной, что петля, что ОП хотел бы избежать. – joews

+1

Идея состоит в абстрактной композиции как функции, реализация вторична. кстати, вот пакет (не зависит от подключения): https://www.npmjs.org/package/connect-compose – vkurchatkin

7

Экспресс принимает массивы для app.use, если у вас есть путь:

var middleware = [connect.urlencoded(), connect.json()]; 
app.use('/', middleware) 

Однако, если вы хотите generic 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); 
     }); 
    }; 
    }); 
} 
0

Старого вопрос, но потребность все еще часто для всех вещей, используя промежуточные программный, как подключить, экспресс или на заказ REQ/res/next.

Это очень элегантное и чисто функциональное решение:

Файла ./utils/compose-middleware.js:

function compose(middleware) { 
    if (!middleware.length) { 
    return function(_req, _res, next) { next(); }; 
    } 

    var head = middleware[0]; 
    var tail = middleware.slice(1); 

    return function(req, res, next) { 
    head(req, res, function(err) { 
     if (err) return next(err); 
     compose(tail)(req, res, next); 
    }); 
    }; 
} 

module.exports = compose; 

Конечный результат compose(middlewareList) является единственным промежуточным слоем, который инкапсулирует вся цепочка промежуточного программного обеспечения изначально была предоставлена.

Тогда просто импортировать его и использовать, как это:

Файл app.js:

var connect = require('connect'); 
var compose = require('./utils/compose-middleware'); 

var middleware = compose([ 
    connect.urlencoded(), 
    connect.json() 
]); 

var app = connect(); 
app.use(middleware); 
Смежные вопросы