2012-06-04 48 views
2

我在學習Node.js,並且已經閱讀了一些教程,例如用於學習核心功能的Node Beginner Book。但是我越讀一些例子,我開始收集越多的懷疑。Express/Connect中間件如何工作?

在進一步的實例中,從一個教程獲得,我們可以看到,對於一個CRUD「讀」爲鍵/documents/titles.json請求,我們返回值:

app.get('/documents/titles.json', loadUser, function(req, res) { 
    Document.find({ user_id: req.currentUser.id },[], { sort: ['title', 'descending'] }, 
    function(err, documents) { 
    res.send(documents.map(function(d) { 
     return { title: d.title, id: d._id }; 
    })); 
    }); 
}); 

在此示例中,函數loaduser()是用於認證目的:

function loadUser(req, res, next) { 
    if (req.session.user_id) { 
     User.findById(req.session.user_id, function(err, user) { 
     if (user) { 
      req.currentUser = user; 
      next(); 
     } else { 
      res.redirect('/sessions/new'); 
     } 
     }); 
    } 
} 

我不明白的是:

  1. 我想那個node.js,在開始執行app.get之前,它會去loaduser函數。 loadUser()函數有三個參數:req,res,next,但我至少沒有看到你如何從app.get()傳遞「req」參數到loadUser()。它從哪裏來?
  2. loadUser()功能,當你執行next(),這意味着功能app.get()「可以繼續其過程,但這個req.currentUser =用戶,是在app.get()功能?
  3. 內部使用loadUser()功能相同的REQ,當您執行res.redirect()代碼,將自動斷開上app.get()功能的過程中,正確的它看起來像它不返回Document.find()
+0

關於您的第一個代碼示例:您絕對*無法*從異步函數中返回值。這不是異步代碼的工作方式。沒有返回值。你可以做的是調用另一個函數。 – Tomalak

回答

9

你問的問題是關於Express框架內部明確:

  1. 當你調用與loadUser和最終的功能函數app.get(路線,loadUser,最終)Express將製作堆棧(陣列),它會知道,當你調用next應該執行以下功能在與req和res params相同的堆棧中。

  2. 當你下一次調用它時,它會傳遞給中間件堆棧中的下一個函數。

  3. 由於您調用res.redirect並且不調用返回,它不會傳遞到堆棧中的下一個函數(使用Document.find的函數)。

資源:

http://howtonode.org/getting-started-with-express

+0

,非常感謝您的回答。它完全清除了我的混合腦:-)。 – user1106811

+5

您應該將此標記爲接受的答案 – timoxley

0

我認爲,爲了熟悉這種你需要熟悉中間件的想法,它是如何在連接框架中使用。

我發現很少有文章,這個主題解釋得很好。看看有:

http://howtonode.org/connect-it 這裏http://stephensugden.com/middleware_guide/

主要的想法是,你有一組層的每一次當新的請求到達時,它經過各個層次,各個層次,你可以決定做什麼接着就,隨即。您可以在某個級別停止,執行某些操作並返回響應,也可以將它傳遞到下一層