Hen*_*son 5 javascript node.js
做完作业:
背景故事:我想尝试编写自己的框架但是我遇到了一些麻烦,很可能是由于没有完全理解它.
我想要实现的是一个如下所示的语法:
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 });
Run Code Online (Sandbox Code Playgroud)
我知道具有相同语法的Express框架但是阅读它们的源代码仍然让我无法理解.
这可能是一项微不足道的任务,但我还是无法生产它.
尝试require('./app');在应用程序更深的文件中生成一个未定义的对象,所以我猜测服务器是一个单例对象.
那我试过了什么?
我当前的代码看起来像这样,不知怎的,我觉得这是要走的路,但我显然不能这样做.
我省略了所有require();语句以使其更具可读性.
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;
Run Code Online (Sandbox Code Playgroud)
在撰写本文时,我正在尝试使用方法扩展此对象get().
index.js:
var app = require('./server');
app.createServer().listen('1337');
Run Code Online (Sandbox Code Playgroud)
该router.route()位基本上将请求向前发送到应用程序和router.js文件内部我做了一些魔术并将请求路由到一个映射(到目前为止)到/ urlThatWasRequested的函数
这是我想留下的行为.我知道这可能是一个非常高的顺序,但我的所有代码都很容易丢弃,我不怕重写整个代码库,因为这是我自己的项目.
我希望这足以解释我的问题,请说出我应该添加的内容以使其更加清晰.
提前致谢!
fre*_*ish 11
我不确定你的问题是什么,但这里有一些想法:
1)您在这里创建一个循环引用:
var app = module.exports = {
// some other code
}
exports.app = app;
Run Code Online (Sandbox Code Playgroud)
您添加app为属性app.最后一行没有必要.
2)你需要掌握处理程序app.你可以尝试这样的事情:
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
}
Run Code Online (Sandbox Code Playgroud)
请注意,您可以更改此行:if (handler.url == path)以handler.url正则表达式的方式对其进行测试path.当然,你可以实现.get和.post变种,但是从我的经验更容易检查请求是否是GET或POST 内部处理程序.现在您可以使用上面的代码:
app.route('/someUrl', function(req, res){ //do stuff here });
Run Code Online (Sandbox Code Playgroud)
另一件事是我向你展示的代码只触发它匹配的给定URL 的第一个处理程序.您可能希望制作涉及许多处理程序(即中间件)的更复杂的路由.在这种情况下,架构会有所不同,例如:
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();
},
Run Code Online (Sandbox Code Playgroud)
现在你可以使用你的路线
app.route('/someUrl', function(req, res, next){
//do stuff here
next(); // <--- this will take you to the next handler
});
Run Code Online (Sandbox Code Playgroud)
这将带你到另一个处理程序(如果没有更多的处理程序,则抛出异常).
3)关于这些话:
试图要求('./ app'); 在应用程序更深的文件中生成一个未定义的对象,所以我猜测服务器是一个单例对象.
事实并非如此.require始终返回对模块对象的引用.如果你看到了undefined,那么你搞砸了别的东西(改变了模块本身?).
最后说明:我希望它有所帮助.编写自己的框架可能是一项艰巨的任务,尤其是因为已经存在像Express这样的优秀框架.祝你好运!
编辑
实施.get和.set方法实际上并不困难.你只需要改变这样的route功能:
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');
},
Run Code Online (Sandbox Code Playgroud)
然后在路由算法中检查type属性是否已定义.如果不是那么使用该路线(undefined类型意味着:始终路线).否则另外检查请求的方法是否与类型匹配.而且你已经完成了!
| 归档时间: |
|
| 查看次数: |
16055 次 |
| 最近记录: |