开始学习nodejs!

  参考书籍:The Node Beginner Book ,所有问题和讨论都围绕本书。

  1.学习nodejs需要具备的基础知识:

  js基本语法,基本上写过前端的都能满足,原生js、jquery

  2.nodejs与基础知识相比,学习的点在哪里?

  nodejs本身就是js,如下:

var http = require("http");

http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);

  nodejs使用模块化编程

    关于模块化,只要知道它解决什么问题即可:

      模块化其实就是封装,把一组特定功能的代码封装在一个类似java jar包的模块中,方便复用,使结构清晰,等等

      js从原生的顺序无模块代码,到自执行函数、jquery匿名函数、到CommonJS,就是一个模块化进程,习惯使用jquery的童鞋不应该抵触新的模块化编程

    nodejs的模块化,我们都要学习哪些?

      1.使用现成模块工具

        如上代码,copy到server.js中,cmd命令下执行   node server.js

        访问 http://localhost:8888/  ,一个简单的web服务就成功访问了!

        这里使用   require("http") 调用http模块,这个是nodejs内置的

      2.自己封装模块

        server.js可能我们会加入更多其他的路由代码,这时候我们可以把启动功能迁移出去,如何办?

        

var http = require("http");

function start() {
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
} http.createServer(onRequest).listen(8888);
console.log("Server has started.");
} exports.start = start;

        server.js修改一下,把启动web服务器的代码移到start方法体中,

      使用  exports.start = start  向外部暴露web启动方法

      习惯上,我们使用index.js来启动app,代码如下:

var server = require("./server");

server.start();

      执行 node index.js  效果一样!

  3.完善web服务器的路由功能

    可以发现,访问8888的任意资源都会返回helloworld,why?

    这就说明我们这个服务器其实是缺少路由功能的,也可以说,路由功能使用基本的if else即可实现,我们先获取request请求路径

var http = require("http");
var url = require("url"); function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
} http.createServer(onRequest).listen(8888);
console.log("Server has started.");
} exports.start = start;

    使用url即可获取资源请求路径。

    习惯上,使用router.js来负责路由分发:

function route(pathname) {
console.log("About to route a request for " + pathname);
} exports.route = route;

    server.js 导入route模块,  start方法调用route方法即可,

    当然,route其实应该作为服务器的一个组件传入进去,我们可以这样:

var http = require("http");
var url = require("url"); function start(route) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received."); route(pathname); response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
} http.createServer(onRequest).listen(8888);
console.log("Server has started.");
} exports.start = start;

    而index.js相应的:

var server = require("./server");
var router = require("./router"); server.start(router.route);

    事实上,我们现在的路由器还未有任何处理请求的功能,而根据经验,处理各种请求,应该有对应的程序块,

  如果在rout方法体中使用if else,那么代码结构将会极其丑陋

  js的函数式编程给了我们一个启示——可以将不同的请求封装在一个requestHandler中,然后暴露出来供route调用:

  requestHandlers.js

  

function start() {
console.log("Request handler 'start' was called.");
} function upload() {
console.log("Request handler 'upload' was called.");
} exports.start = start;
exports.upload = upload;

  index.js入口脚本来载入handler

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers"); var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload; server.start(router.route, handle);

    handler就是一个字典,针对不同请求,执行不同的处理逻辑

    相应改变的,server.js

var http = require("http");
var url = require("url"); function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received."); route(handle, pathname); response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
} http.createServer(onRequest).listen(8888);
console.log("Server has started.");
} exports.start = start;

    router.js

function route(handle, pathname) {
console.log("About to route a request for " + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname]();
} else {
console.log("No request handler found for " + pathname);
}
} exports.route = route;

    至此,一个简单的路由功能就优雅的实现了!

    路由功能实现了,但是每个请求响应全都是hello world,这个处理起来也不复杂,只需要让handler返回结果,然后response将结果输出出去即可!



  

nodejs入门学习笔记一——一个完整的http路由服务实现的更多相关文章

  1. nodejs入门学习笔记二——解决阻塞问题

    在最开始,我们要弄清楚node会什么会存在阻塞? node是这么标榜自己的:“在node中除了代码,所有一切都是并行执行的!” 意思是,Node.js可以在不新增额外线程的情况下,依然可以对任务进行并 ...

  2. SuperSocket学习笔记(一)-一个完整的例子

    一.什么是SuperSocket 以下是作者的介绍 执行以下命令,获取SuperSocket项目 $ git clone https://github.com/kerryjiang/SuperSock ...

  3. WCF学习笔记(1)-一个完整的例子

    一.开发环境 IDE:VS2013 OS:Win10 IIS:IIS 10 二.开发流程 1.项目结构 2.添加一个WCF程序 3.删除系统自动生成的两个文件IService1.cs和Service1 ...

  4. DirectX11 学习笔记4 - 一个完整的封装框架

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3EzNjExMDYzMDY=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  5. 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)

    [原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...

  6. OpenCV入门学习笔记

    OpenCV入门学习笔记 参照OpenCV中文论坛相关文档(http://www.opencv.org.cn/) 一.简介 OpenCV(Open Source Computer Vision),开源 ...

  7. Hadoop入门学习笔记---part4

    紧接着<Hadoop入门学习笔记---part3>中的继续了解如何用java在程序中操作HDFS. 众所周知,对文件的操作无非是创建,查看,下载,删除.下面我们就开始应用java程序进行操 ...

  8. Hadoop入门学习笔记---part3

    2015年元旦,好好学习,天天向上.良好的开端是成功的一半,任何学习都不能中断,只有坚持才会出结果.继续学习Hadoop.冰冻三尺,非一日之寒! 经过Hadoop的伪分布集群环境的搭建,基本对Hado ...

  9. PyQt4入门学习笔记(三)

    # PyQt4入门学习笔记(三) PyQt4内的布局 布局方式是我们控制我们的GUI页面内各个控件的排放位置的.我们可以通过两种基本方式来控制: 1.绝对位置 2.layout类 绝对位置 这种方式要 ...

随机推荐

  1. storm启动supervisor源码分析-supervisor.clj

    supervisor是storm集群重要组成部分,supervisor主要负责管理各个"工作节点".supervisor与zookeeper进行通信,通过zookeeper的&qu ...

  2. es6基础系列五--数组的拓展

    Array.from() 用于将两类对象转为真正的数组,类似数组对象和可遍历对象(包括数据结构Set和Map)转化为数组 格式:Array.from(arrayLike[, mapFn[, thisA ...

  3. hdu1054

    /* [题意] 给定一棵树,标记一节点,则与该节点所连的边都被标记,问最少需要标记多少个节点使得所有边都被标记: 或者说给定一个树型城堡,在交叉路口放一个士兵,则与该路口相连的路都被守住, 问最少需要 ...

  4. idea调试SpringMvc, 出现:”Can't find catalina.jar"错误的解决方法

    用gradle构建的项目,点击运行出现以下错误提示: Error running PraticeWeb: Can't find catalina.jar 21:54 Error running Pra ...

  5. 26、生鲜电商平台-RBAC系统权限的设计与架构

    说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上分析实现的策略以及基于目前两种比较流行的权限设计思想 ...

  6. C4-总结

    呃,很难受的比赛,中途做到口干舌燥还想尿尿//哦,题目,出的很棒,什么都可以做做,什么都做不下来. 怎么说呢?好像也没犯什么错误,除了日常开始手抖了一下...后面状态进入挺快的,而且遗憾?3-2吧,t ...

  7. 清北刷题冲刺 10-29 a.m

    遭遇 /* 因为选的楼是个集合,与顺序无关 而且总花费=c[1]+c[2]+c[3]+|h[1]-h[2]|+|h[2]-h[3]| 我们规定走的顺序从高到低,那么绝对值就可以去掉 所以就可以约掉中间 ...

  8. Spring MVC 简述:从MVC框架普遍关注的问题说起

    任何一个完备的MVC框架都需要解决Web开发过程中的一些共性的问题,比如请求的收集与分发.数据前后台流转与转换,当前最流行的SpringMVC和Struts2也不例外.本文首先概述MVC模式的分层思想 ...

  9. SSM整合文档

    SSM整合文档 v2 一. 文件说明 文件名 描述 spring-servlet.xml 配置SpringMvc框架相关 applicationContext.xml 配置Spring容器 sprin ...

  10. 我的省选 Day -10

    Day -10 今天的分数也许会比昨天更低.. 感觉2017年比远古时代的2007年的第一试难诶. 估个分数好了,我猜88分(为什么猜了一个这么吉利的数字??到时候出来没几分就啪啪啪打脸了) 和昨天一 ...