2012-07-11 21 views
5

Bài tập về nhà làm:URL trong Node.js

The Node Beginner Book

How do I get started with Node.js [closed]

Structuring handlers in Node

chút lịch sử: Tôi muốn thử và viết khuôn khổ của riêng tôi nhưng tôi đang chạy vào một số rắc rối , rất có thể là do không hiểu nó đầy đủ.

Những gì tôi muốn đạt được là một cú pháp trông như thế này:

var app = require('./app'); //this part is understood and it works in my current code. 
app.get('/someUrl', function(){ //do stuff here }); 
app.post('/someOtherUrl', function(){ //do stuff here }); 

tôi biết Express-framework có cú pháp này tương tự nhưng đọc mã nguồn của họ vẫn vượt quá tầm hiểu tôi.

Đây có thể là một nhiệm vụ tầm thường để đạt được nhưng tôi chưa thể tạo ra nó.

Cố gắng require('./app'); trong một tệp sâu hơn trong ứng dụng tạo ra đối tượng không xác định, vì vậy tôi đoán rằng máy chủ là đối tượng đơn lẻ.

Vì vậy, tôi đã thử những gì?

Mã hiện tại của tôi trông như thế này, và bằng cách nào đó tôi cảm thấy như đây là con đường để đi, nhưng tôi không thể làm điều đó như thế này.

Tôi bỏ qua tất cả các tuyên bố require(); để giữ cho nó dễ đọc hơn.

server.js:

var app = module.exports = { 
    preProcess: function onRequest(request, response){ 
     processor.preRequest(request); //this object adds methods on the request object 
     var path = urllib.parse(request.url).pathname; 
     router.route(urls, path, request, response); 
    }, 
    createServer: function() { 
     console.log("Server start up done."); 
     return this.server = http.createServer(this.preProcess); 
    } 
}; 

exports.app = app; 

Tại thời điểm viết bài Tôi đang thử nghiệm với mở rộng đối tượng này với một phương pháp get().

index.js:

var app = require('./server'); 
app.createServer().listen('1337'); 

bit router.route() cơ bản gửi yêu cầu trở đi vào các ứng dụng và bên trong router.js-file tôi làm một số phép thuật và định tuyến các yêu cầu trở đi đến một chức năng mà các bản đồ (cho đến nay) đến/urlThatWasRequested

Đây là hành vi tôi muốn bỏ lại phía sau. Tôi biết điều này có thể là một thứ tự khá cao nhưng tất cả mã của tôi có thể dễ dàng bị loại bỏ và tôi không sợ viết lại toàn bộ codebase vì đây là dự án của riêng tôi.

Tôi hy vọng điều này là đủ trong việc giải thích câu hỏi của tôi nếu không, hãy nói những gì tôi nên thêm để làm cho điều này rõ ràng hơn một chút.

Cảm ơn trước!

Trả lời

11

Tôi không chắc chắn chính xác những gì câu hỏi của bạn, nhưng đây là một vài suy nghĩ:

1) Bạn đang tạo một tham chiếu vòng tròn ở đây:

var app = module.exports = { 
    // some other code 
} 
exports.app = app; 

Bạn thêm app như một tài sản của app. Không cần dòng cuối cùng.

2) Bạn cần giữ các trình xử lý trong app. Bạn có thể thử một cái gì đó như thế này:

var app = module.exports = { 
    handlers : [], 
    route : function(url, fn) { 
     this.handlers.push({ url: url, fn: fn }); 
    }, 
    preProcess: function onRequest(request, response){ 
     processor.preRequest(request); 
     var path = urllib.parse(request.url).pathname; 
     var l = this.handlers.length, handler; 
     for (var i = 0; i < l; i++) { 
      handler = this.handlers[i]; 
      if (handler.url == path) 
       return handler.fn(request, response); 
     } 
     throw new Error('404 - route does not exist!'); 
    }, 
    // some other code 
} 

Lưu ý rằng bạn có thể làm thay đổi dòng này: if (handler.url == path) theo cách như vậy mà handler.url là một biểu hiện thường xuyên và bạn kiểm tra path chống lại nó. Tất nhiên, bạn có thể thực hiện các biến thể .get.post, nhưng từ kinh nghiệm của tôi, việc kiểm tra xem yêu cầu có phải là dễ dàng hơn hay không GET hoặc POSTtrong bộ xử lý. Bây giờ bạn có thể sử dụng đoạn mã trên như thế này:

app.route('/someUrl', function(req, res){ //do stuff here }); 

Một điều khác là đoạn code tôi đã thể hiện bạn chỉ bắn các xử lý đầu tiên cho một URL cho nó phù hợp. Bạn có thể muốn tạo các tuyến phức tạp hơn liên quan đến nhiều trình xử lý (ví dụ: phần giữa). Kiến trúc sẽ là một chút khác nhau trong trường hợp đó, ví dụ:

preProcess: function onRequest(request, response){ 
    var self = this; 
    processor.preRequest(request); 
    var path = urllib.parse(request.url).pathname; 
    var l = self.handlers.length, 
     index = 0, 
     handler; 
    var call_handler = function() { 
     var matched_handler; 
     while (index < l) { 
      handler = self.handlers[index]; 
      if (handler.url == path) { 
       matched_handler = handler; 
       break; 
      } 
      index++; 
     } 
     if (matched_handler) 
      matched_handler.fn(request, response, function() { 
       // Use process.nextTick to make it a bit more scalable. 
       process.nextTick(call_handler); 
      }); 
     else 
      throw new Error('404: no route matching URL!'); 
    }; 
    call_handler(); 
}, 

Bây giờ bên tuyến đường của bạn, bạn có thể sử dụng

app.route('/someUrl', function(req, res, next){ 
    //do stuff here 
    next(); // <--- this will take you to the next handler 
}); 

mà sẽ đưa bạn đến xử lý khác (hoặc ném ngoại lệ nếu không có nhiều trình xử lý hơn).

3) Về những lời này:

Đang cố gắng để yêu cầu ('./ ứng dụng'); trong một tệp sâu hơn trong ứng dụng tạo ra một đối tượng không xác định , vì vậy tôi đoán rằng một máy chủ là một đối tượng đơn lẻ.

Điều đó không đúng. require luôn trả về tham chiếu đến đối tượng mô-đun. Nếu bạn thấy undefined, thì bạn đã làm rối tung một thứ khác (thay đổi chính mô-đun đó?).

Lưu ý cuối cùng: Tôi hy vọng nó sẽ giúp ích một chút. Viết khuôn khổ của riêng bạn có thể là một công việc khó khăn, đặc biệt là kể từ khi đã có khung công tác xuất sắc như Express. Chúc may mắn!

EDIT

Thực hiện .get.set phương pháp thực sự là không khó. Bạn chỉ cần thay đổi route chức năng như thế này:

route : function(url, fn, type) { 
    this.handlers.push({ url: url, fn: fn, type: type }); 
}, 
get : function(url, fn) { 
    this.route(url, fn, 'GET'); 
}, 
post : function(url, fn) { 
    this.route(url, fn, 'POST'); 
}, 

và sau đó trong routing thuật toán bạn kiểm tra xem type tài sản được xác định.Nếu không, hãy sử dụng tuyến đường đó (phương tiện loại undefined: luôn tuyến đường). Nếu không, hãy kiểm tra xem phương thức của một yêu cầu có khớp với loại không. Và bạn đã hoàn tất!

+0

Cảm ơn câu trả lời! :) Câu hỏi của tôi là "Cách tạo cú pháp .get(), .post()". Tôi có thể phải thay đổi câu hỏi. Lý do tại sao tôi muốn kiềm chế không kiểm tra để có được/đăng trong các chức năng chính nó chỉ là vì sở thích trong dự án này. Cám ơn đã chỉ tôi hướng đi đúng! :) Ngoài ra tôi có một tập tin xử lý, nơi tôi thêm rất nhiều xử lý mà bản đồ để chức năng của cùng một tên tôi không chắc chắn nếu điều đó đã được thực hiện rõ ràng. –

+0

@lưu lượng tôi thấy. Tôi đã cập nhật câu trả lời! – freakish

+0

điều này có thể là một câu hỏi hoàn toàn mang tính định kỳ nhưng thuộc tính trình xử lý không được instatiated, nó chỉ là không xác định. –