2013-08-15 24 views
5

Tôi có một rất đơn giản "server.js" thiết lập mà tôi đang cố gắng để chạy:Cách thích hợp để xử lý các kết nối mongoose với express.js là gì?

var express = require('express'), 
    wines = require('./routes/testscripts'); 

var app = express(); 

app.get('/first_test', wines.popSingleData); 

app.listen(3000); 
console.log('Listening on port 3000...'); 

này được thiết lập để kết nối với localhost:3000

Khi tôi hướng đến localhost:3000/first_test, nó gọi là "popSingleData "phương pháp trong testscript.js:

... 
    var mongoose = require('mongoose'); 

    mongoose.connect('mongodb://localhost/test'); 

    var db = mongoose.connection; 

    console.log('include called'); 

exports.popSingleData = function(req, res) { 

// var mongoose = require('mongoose'); 

// mongoose.connect('mongodb://localhost/test'); 

// var db = mongoose.connection; 

    console.log('function called'); 

    db.on('error', console.error.bind(console, 'connection error:')); 
    console.log('error handler set'); 
    db.once('open', function callback() { 
     //yay! 
     console.log("DB Opened"); 

     var someSchema = require('../models/someSchema'); 

     someSchema.find(function (err, found){ 
      if (err) 
      { 
       console.log('err'); 
      } 

      if(found.length != 0) 
      { 
       console.log("Found Data:"); 
       console.log(found); 
       for(var i = 0; i < found.length; i++) 
       { 
        res.jsonp((found[i])); 
       } 
      } 
     }); 


    }); 

}; 
... 

các dòng đang gây ra vấn đề là người đầu tiên 3:

var mongoose = require('mongoose'); 
mongoose.connect('mongodb://localhost/test'); 
var db = mongoose.connection; 

Khi chúng được khai báo bên trong hàm, tập lệnh chạy như mong đợi, in ra các đối tượng JSON mà nó tìm thấy từ cơ sở dữ liệu. Khi chúng được xác định trong testscript.js, nhưng nằm ngoài phạm vi của phương thức, chương trình bị treo trên db.once('open', function callback() {...}); command.

Ai đó có thể làm sáng tỏ sự khác biệt xảy ra khi di chuyển 3 dòng mã này? Tôi có thực sự cần phải tạo kết nối mới mỗi lần tôi muốn có một chức năng khác để truy cập cơ sở dữ liệu không?

Trả lời

16

Nếu bạn đã kết nối với cơ sở dữ liệu, sự kiện once sẽ không kích hoạt trở lại. Cơ sở dữ liệu đã được kết nối cho toàn bộ quá trình NodeJs khi nó được kết nối toàn cầu (bên ngoài chức năng).

Cuộc gọi đến mongoose.connect('mongodb://localhost/test'); tạo kết nối và mở nó. Vì vậy, thay vì mở nó trên mỗi cuộc gọi chức năng (đó sẽ là một cách không hiệu quả để tương tác với MongoDB) connect ngay lập tức khi ứng dụng NodeJs được bắt đầu, và xem xét rằng sẽ có một khoảng thời gian kết nối có thể không được khả dụng (vì không đồng bộ) hoặc không khởi động ứng dụng (listen) cho đến khi kết nối hoàn tất (hoặc hết thời gian chờ). Với Mongoose, cho đến khi kết nối được thực hiện, tất cả các lệnh đều được đệm (nhưng đó có thể không phải là hành vi bạn muốn). Bạn có thể sử dụng sự kiện open nếu bạn muốn biết khi kết nối hoàn tất.

Kết nối được tìm thấy tại đây: mongoose.connection nếu bạn sử dụng chức năng connect để tạo kết nối.

Khi kết nối được mở, bạn có thể sử dụng nó từ chức năng popSingleData mà không cần sử dụng sự kiện once và gọi lại. Có một hồ bơi kết nối tự động được duy trì.

Để biết thêm về kết nối, hãy đọc here.

+0

Vì vậy, 'mongoose.connect' là gì tạo kết nối? Vì vậy, lý do nó không hoạt động khi bên ngoài phương pháp, là phương pháp tìm thấy nó đã được mở, do đó, db.once ("mở") không bao giờ xảy ra? –

+0

Có, cố gắng làm rõ điều đó trong câu trả lời của tôi. – WiredPrairie

+0

Tuyệt vời. Đã chuyển mã ra khỏi cuộc gọi lại và dường như nó hoạt động tốt. Cảm ơn rất nhiều! –