2012-05-22 3 views
185

Предположим, у вас есть простой блок кода, как это:Каков параметр «следующий», используемый в Express?

app.get('/', function(req, res){ 
    res.send('Hello World'); 
}); 

Эта функция имеет два параметра, req и res, представляющие запрос и ответ объектов соответственно.

С другой стороны, существуют другие функции с третьим параметром, называемым next. Например, давайте посмотрим на следующий код:

app.get('/users/:id?', function(req, res, next){ // Why do we need next? 
    var id = req.params.id; 
    if (id) { 
     // do something 
    } else { 
     next(); // What is this doing? 
    } 
}); 

Я не могу понять, что точка next() или почему его использования. В этом примере, если id не существует, что на самом деле делает next?

+6

Далее просто разрешает следующий обработчик маршрута в очереди обрабатывать запрос. В этом случае, если идентификатор пользователя существует, он, скорее всего, будет использовать 'res.send' для завершения запроса. Если он не существует, вероятно, будет другой обработчик, который выдает ошибку и завершает запрос. –

+1

, так что вы говорите, что у меня есть app.post ('/ login', function (req, res)) 'after' app.get ('/ users', function (req, res))' он вызовет логин являющийся следующим маршрутом в файле app.js, вызывая next()? – Menztrual

+2

Нет, вы должны сослаться на эту часть документации Express.js: http://expressjs.com/guide.html#passing-route control –

ответ

198

Он передает управление к следующему соответствует маршрут. В примере, который вы указали, например, вы можете найти пользователя в базе данных, если дано id, и назначьте его req.user.

Ниже, вы могли бы иметь маршрут как:

app.get('/users', function(req, res) { 
    // check for and maybe do something with req.user 
}); 

С/пользователями/123 будут соответствовать маршруту в вашем примере первого, который будет первой проверкой и найти пользователь 123; то /users может что-то сделать с результатом.

Route middleware (примечание: ссылка на документацию 2.x, но это проверено как работа на 3.x) является более гибким и мощным инструментом, хотя, на мой взгляд, поскольку он не полагается на конкретный URI или порядок маршрутизации. Я был бы склонен моделировать пример, показанный как это, предполагая Users модели с асинхронным findOne():

function loadUser(req, res, next) { 
    if (req.params.userId) { 
    Users.findOne({ id: req.params.userId }, function(err, user) { 
     if (err) { 
     next(new Error("Couldn't find user: " + err)); 
     return; 
     } 

     req.user = user; 
     next(); 
    }); 
    } else { 
    next(); 
    } 
} 

// ... 

app.get('/user/:userId', loadUser, function(req, res) { 
    // do something with req.user 
}); 

app.get('/users/:userId?', loadUser, function(req, res) { 
    // if req.user was set, it's because userId was specified (and we found the user). 
}); 

// Pretend there's a "loadItem()" which operates similarly, but with itemId. 
app.get('/item/:itemId/addTo/:userId', loadItem, loadUser, function(req, res) { 
    req.user.items.append(req.item.name); 
}); 

Будучи в состоянии контролировать поток, как это очень удобно. Вы могли бы хотеть иметь определенные страницы доступны только пользователь с флагом администратора:

/** 
* Only allows the page to be accessed if the user is an admin. 
* Requires use of `loadUser` middleware. 
*/ 
function requireAdmin(req, res, next) { 
    if (!req.user || !req.user.admin) { 
    next(new Error("Permission denied.")); 
    return; 
    } 

    next(); 
} 

app.get('/top/secret', loadUser, requireAdmin, function(req, res) { 
    res.send('blahblahblah'); 
}); 

Надеется, что это дало вам вдохновение!

+0

, поэтому он просто уменьшает тонну кода в одном маршруте? – Menztrual

+0

Это можно сказать! Я был бы более склонен делать подобные вещи с помощью [промежуточного программного обеспечения маршрута] (http://expressjs.com/guide.html#route-middleware), хотя он не связывает логику с конкретным порядком маршрутов или отдельных структур URI. – Ashe

+0

Ссылка «route middleware» кажется сломанной (суффикс # не влияет), можете ли вы исправить? – djechlin

46

Я также имел проблемы с пониманием следующий(), но this помог

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

app.get("/", function(httpRequest, httpResponse, next){ 
    httpResponse.write("Hello"); 
    next(); //remove this and see what happens 
}); 

app.get("/", function(httpRequest, httpResponse, next){ 
    httpResponse.write(" World !!!"); 
    httpResponse.end(); 
}); 

app.listen(8080); 
+2

Очень лаконично! Благодаря! Но как вы убедитесь, что первый '.get' вызывается, а не второй? – JohnnyQ

+8

@JohnnyQ Это будет сверху до нижнего исполнения – Tapash

4

Далее используется для передачи управления к следующей функции промежуточного программного обеспечения. Если запрос не будет оставлен висящим или открытым.

+1

Я не уверен, что этот ответ добавляет почти семилетний вопрос ... – mherzig

+0

Хотя это краткое изложение, этот комментарий приведет меня к этому: https://expressjs.com /en/guide/writing-middleware.html – hmak

0

Вызов этой функции вызывает следующую функцию промежуточного программного обеспечения в приложении. Функция next() не является частью Node.js или Express API, а является третьим аргументом, который передается функции промежуточного программного обеспечения. Функция next() может быть названа как угодно, но по соглашению она всегда называется «следующая».

Смежные вопросы