362

次のような単純なコードブロックがあるとします。

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

この関数には、要求オブジェクトと応答オブジェクトをそれぞれ表す2つのパラメーターreqとがあります。res

一方、。と呼ばれる3番目のパラメーターを持つ他の関数があります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実際に何をしているのでしょうか。

4

5 に答える 5

298

次の一致するルートに制御を渡します。たとえば、指定した例では、が指定されている場合はデータベースでユーザーを検索し、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'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');
});

これがあなたにいくつかのインスピレーションを与えたことを願っています!

于 2012-05-22T04:26:39.667 に答える
113

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);
于 2016-06-25T15:59:33.133 に答える
93

を理解する前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がサイクルを終了するためです。

しかし、常に「HelloWorld!!!!」が必要ない場合はどうでしょうか。応答します。条件によっては、「ハロープラネット!!!!」が必要になる場合があります。応答。上記のコードを変更して、何が起こるか見てみましょう。

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。そして、はい、あなたは突風を持っているかもしれません。条件がtrueの場合、最初のミドルウェア関数をスキップして次のミドルウェア関数を呼び出すと、"Hello Planet !!!!"応答が返されます。

したがって、次に、ミドルウェアスタック内の次の関数に制御を渡します。

最初のミドルウェア関数が応答を返さないが、ロジックの一部を実行してから、2番目のミドルウェア関数から応答を返す場合はどうなりますか。

以下のようなもの:-

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

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

この場合、両方のミドルウェア関数を呼び出す必要があります。したがって、2番目のミドルウェア関数に到達する唯一の方法はnext()を呼び出すことです。

次への呼び出しを行わない場合はどうなりますか。2番目のミドルウェア関数が自動的に呼び出されることを期待しないでください。最初の関数を呼び出した後、リクエストはハングしたままになります。2番目の関数が呼び出されることはなく、応答が返されることもありません。

于 2018-03-20T15:17:16.320 に答える
15

Nextは、次のミドルウェア機能に制御を渡すために使用されます。そうでない場合、リクエストはハングまたはオープンのままになります。

于 2017-04-14T19:58:10.713 に答える
0

expressまた、次のミドルウェアを呼び出さない理由を追加して、それを制御できるようにします。ノードは非同期であるため、Expressが非同期呼び出しの終了を待たずに次のミドルウェアを呼び出すと、応答が不完全になるかエラーが含まれる可能性があります。そのため、ユーザーは次のミドルウェア関数をいつ呼び出すかを制御できます。

于 2022-01-01T11:40:15.913 に答える