Каков параметр "следующий", используемый в 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 на самом деле?

Ответ 1

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

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

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

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

Промежуточное ПО маршрутов - более гибкий и мощный инструмент, хотя, на мой взгляд, поскольку оно не зависит от конкретной схемы 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 because userId was specified (and we found the user).
});

// Pretend there 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');
});

Надеюсь, это вдохновило тебя!

Ответ 2

У меня также возникла проблема с пониманием next(), но это помогло

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);

Ответ 3

Прежде, чем понять next, вам нужно иметь небольшое представление о цикле "запрос-ответ" в узле, хотя и не очень подробно. Он начинается с того, что вы делаете HTTP-запрос для определенного ресурса, и заканчивается, когда вы отправляете ответ обратно пользователю, то есть когда вы сталкиваетесь с чем-то вроде res.send(‘Hello World);

Давайте посмотрим на очень простой пример.

app.get('/hello', function (req, res, next) {
  res.send('USER')
})

Здесь нам не нужна функция next(), так как resp.send завершит цикл и вернет элемент управления промежуточному программному обеспечению маршрута.

Теперь давайте посмотрим на другой пример.

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

app.get('/hello', function (req, res, next) {
  res.send("Hello Planet !!!!");
});

Здесь у нас есть 2 функции промежуточного программного обеспечения для одного и того же пути. Но вы всегда получите ответ от первого. Потому что он монтируется первым в стеке промежуточного программного обеспечения, а res.send завершит цикл.

Но что, если мы всегда не хотим "Hello World !!!!" ответ обратно. Для некоторых условий мы можем хотеть "Привет Планета !!!!" ответ. Давайте изменим приведенный выше код и посмотрим, что произойдет.

app.get('/hello', function (req, res, next) {
  if(some condition){
    next();
    return;
  }
  res.send("Hello World !!!!");  
});

app.get('/hello', function (req, res, next) {
  res.send("Hello Planet !!!!");
});

Что здесь делает next. И да, у тебя могут быть подкрепления. Она пропустит первую функцию промежуточного программного обеспечения, если условие выполнено, и вызовет следующую функцию промежуточного программного обеспечения, и вы получите ответ "Hello Planet !!!!".

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

Что если первая функция промежуточного программного обеспечения не отправляет ответ, но выполняет часть логики, а затем вы получаете ответ от второй функции промежуточного программного обеспечения.

Примерно так: -

app.get('/hello', function (req, res, next) {
  // Your piece of logic
  next();
});

app.get('/hello', function (req, res, next) {
  res.send("Hello !!!!");
});

В этом случае вам нужно вызвать обе функции промежуточного программного обеспечения. Таким образом, единственный способ получить доступ ко второй функции промежуточного программного обеспечения - это вызвать next();

Что делать, если вы не позвоните следующим. Не ожидайте, что вторая функция промежуточного программного обеспечения будет вызвана автоматически. После вызова первой функции ваш запрос останется висеть. Вторая функция никогда не будет вызвана, и вы не получите ответ.

Ответ 4

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

Ответ 5

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