2017-03-29 16 views
1

で働くん2つのコールバックがエラーhandling.Ifためのもので、基本的に、ここ2、コールバックと1つのgetルートどのようにコールバックが実際に以下のノードのjs

app.get('/login', function(req, res, next) { 
    res.sendFile(__dirname + '/public/views/login.html'); 
}); 
app.use(function (req, res, next) { 
     console.log("first callback 1"); 
     var err = new Error('Not Found'); 
     err.status = 404; 
     next(err); 
     console.log("first callback 2"); 
}); 
app.use(function (err, req, res, next) { 
    // set locals, only providing error in development 
     console.log("second callback"); 
     res.locals.message = err.message; 
     res.locals.error = req.app.get('env') === 'development' ? err : {}; 
    // render the error page 
    res.status(err.status || 500); 
    res.render('error'); 
    console.log("error send"); 
}); 

を持っている私のコードで私はアプリを実行し、localhost:3000/homeに行き、コールが戻ってくるので、経路がなく、404エラーが発生するためです。

localhost:3000/loginに行った場合、login.htmlページが表示されていますが、コールバックが呼び出されていません。エラーはありませんが、コールバックの最初のコンソールメッセージが表示されるはずです。コールバックを呼び出さない?

私がコールバックについて読んだのは、パスを指定しなければ、すべてのルートを呼び出すということです。しかし、なぜここにいないのですか?誰かがこれを読んで私が間違っている場合は私をクリアする時間がかかります。

+2

あなたの 'app.get( '/ login' ...)を一番下に置いてみてください。 –

+0

@AlexPánekは今すぐ取得しました。しかし、それはどういう意味ですか。コールバックはすべてのルートを呼び出す必要があります。しかし、なぜそれが最下位になると呼び出されなかったのですか。これを理解するのを助けてください。 – user7350714

+0

詳細を知っているが、ミドルウェア(app.use')を追加する前に追加されたルートハンドラ( 'app.get')はミドルウェアについて知らないようだ。 –

答えて

2

これはコールバックに関するものではありません。これは、ミドルウェア(プラグイン/モジュール)アーキテクチャがExpressでどのように機能しているか(そして偶然、他のフレームワークもたくさんありますが、すべてのフレームワークがこのように機能するわけではありません)

エクスプレスによって実装実際のコードは、モジュール式と少し複雑ですが、基本的にはこのようなものに動作します:だから、あなたが見る

var middlewares = []; 

var app = { 
    use: function (callback) { 
     middlewares.push({path:"", callback: callback}); 
    }, 
    get: function (path, callback) { 
     middlewares.push({path: path, callback: callback}); 
    } 
} 

を、アイデアは単純です。本当に素晴らしいことはありません。 .use()は、すべてのパスで実行するコードを追加するために使用され、.get()は、パスが一致する場合に実行するコードを追加するために使用されます。

だから我々は今、配列をループすることにより、サーバーへの各要求を処理することができます。

// WARNING: NOT REAL CODE, this is only meant as an illustration 

function processRequest (req, res) { 
    for (var i=0; i<middlewares.length; i++) { 
     var whatToDo = middlewares[i]; 

     if (whatToDo.path == "") { // no need to check path 
      whatToDo.callback(err, req, res, next); 
     } 
     else if (whatToDo.path == req.path) { // check if path match 
      whatToDo.callback(req, res, next); 
     } 
    } 
} 

をだから、それがどのように動作するかです。もちろん、ミドルウェアは非同期なので、実際のコードではforループは使用できません。これは実際にはnext()の機能です - ミドルウェアをリンクしたリスト(リンクされた関数のみ)のようにループします。 next()が呼び出されない場合、ループは停止します。

+0

配列を非同期でループする方法に本当に関心があるなら、私はそれを答えに加えることができます。今のところ私は上記の偽のコードはフレームワークが何をしているかのヒントを与えるのに十分だと思います。 – slebetman

+1

それは素敵な説明でした。配列を非同期的にループする方法の良い例を共有するともっと役に立ちます... – user7350714

関連する問題