NodeJs——(1)封装,调用,执行,访问路径,http,函数编程,等待函数,事件监听

(1)如何封装一个模块;

首先,我们建立一个js文件,例如命名为test.js;

然后在里面写一个函数,函数名任意;

然后通过exports.变量名,将函数赋值给这个变量;

如代码:

function
test(){   
//请注意这个函数名
    console.log("1");
}
exports.testBegin=
test;  
//等号后面的test,指的是上面的函数名。等号前面的testBegin,是调用时的函数名(注意区别)

 

这个test.js的文件就写完了,这是一个模块,他的效果是调用该函数后,输出1;

另外,不要问我这个exports是什么,我暂时也不知道。

 

 

(2)如何调用一个模块

在封装模块的前提下,我们新建一个文件,例如a.js,来调用之前封装的test.js模块;

方法是:

var test = require("./test");   //调用该模块
test.testBegin();   //调用该模块的方法(注意方法名是test.js中exports后面的变量名);

 

注意调用时的方法名,并非是test.js中的函数名test;

 

 

(3)如何执行一个node.js的文件

我们现在需要执行a.js这个调用了封装模块的文件了,执行他的方法,和执行普通的node.js的文件的方法并没有什么不同;

在a.js这个文件的目录下,打开命令行。windows是shift+鼠标右键;

像下面这样输入即可:

然后将输出1,感觉执行执行python文件那样

 

(4)获得访问者想要访问的路径


首先上图,其中pathname指的是路径;而query指的是请求之类的东西(暂时不关心);

假如我们想要获得pathname(即字符串“start”),我们该怎么办呢?

 

方法:

①首先,需要获取访问者需要访问的路径,方法是通过http的方法createServer

 

具体来说:

我们先require一个http模块:

var http = require("http");

 

然后调用其方法,创建一个服务器:

http.createServer(onRequest).listen(8888);

注意,这个方法监听的是8888端口,其参数是一个函数;

 

然后我们书写这个函数的内容:

function onRequest(request, response) {
    console.log(request.url);
}

这个函数的第一个参数request是用户访问的一些东西,我们需要的是其url变量;假设我们访问地址是这样的:

http://127.0.0.1:8888/index/loading?start

请注意红色部分,那么服务器在console.log输出的是

/index/loading?start

 

 

②我们下来要对这个url做点什么了;

虽然直接对上面那个参数进行操纵也可以,但这太笨了,让我们来require一个新的模块url

var url = require("url");

 

 

③调用这个新模块的方法parse,将第一步获得的url地址,作为其参数,再调用其方法pathname,就可以获得我们想要的东西了;

具体而言,需要这么一段代码:

var pathname = url.parse(request.url).pathname;

 

这个pathname就是我们需要的东西了;

 

把所有代码综合起来,是这样的:

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

 

然后运行之:

 

我们随便访问一个本地的地址:

http://127.0.0.1:8888/index/loading?start

 

发现,/index/loding这部分被正常的显示出来了。

另外,favicon.ico是该网站的图标,据说很多服务器是会默认读取的;

 

假如我们直接访问:http://127.0.0.1:8888,显示是这样的

 

 

 

 

(5)关于http

我们之前有了这么一段代码(已delete掉无关部分):

var http = require("http");
function onRequest(request, response) {
    response.writeHead(200, {"Content-type": "text/plain"});
    response.write("Hello word!");
    response.end();
}
http.createServer(onRequest).listen(8888);

 

其中,http调用了NodeJs自带的一个模块“http”,而这个模块是一个服务器模块;

而createServer是这个模块的方法,效果是返回一个对象,而这个对象有一个listen的方法;

当然,由于你和我,也许都是新手,因此我们尚没有搞清楚这个到底是怎么运作的;但如果有一定经验的话,可以猜到,这个listen是监听,监听的是8888端口;如果去掉这部分会怎么样?经过测试,服务器并没有运行,如图:

 

而onRequest函数呢,从名字可以猜到,这个函数的效果是“当请求的时候做些什么”,我们来看其函数:

function onRequest(request, response) {
    response.writeHead(200);
    response.write("Hello word!");
    response.end();
}

 

这个函数有两个参数:request和response,顾名思义,请求和响应。

request请求指用户访问的时候,相关的信息;

response指服务器的响应,会做些什么;这个函数的三个方法,都是response相关的;

 

第一个:response.writeHead方法,具体来说,就是HTTP响应报文的头行;

这个指HTTP通信的响应报文中的头部分,如果没有基础的话,暂时不需要关心,写200即可,这里的200,是约定俗称的请求成功时的返回;

具体搜:

http://blog.csdn.net/fh13760184/article/details/6840696

response.writeHead(statusCode,[reasonPhrase], [headers])

 

 

第二个:response.write方法,具体来说,是HTTP响应报文;

简单理解,负责发送正文中的一部分,可以同时发送多个不一样的;

在上面搜:

response.write(chunk,encoding='utf8')

 

第三个:response.end方法,具体来说每一个响应的结束,必须要调用这个方法,然后服务器会认为这条信息已经发送完毕了。

 

综合效果来说,当我们访问:http://127.0.0.1:8888/时,浏览器会出现:

Hello word!

这样的文字。

 

 

(6)函数式编程

所谓函数式编程,简单的理解,就是将函数作为参数传递;

目前有四个文件:

index.js

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);   //调用该模块的方法(注意方法名是test.js中exports后面的变量名)

 

server.js

var http = require("http");
var url = require("url");
function start(route, handle) {
    var count = 0;

    function onRequest(request, response) {
        console.log(count++ + "#:");
        var pathname = url.parse(request.url).pathname;
        console.log("Request for " + pathname + " recived.");

        route(handle, pathname);    //来源于上面的start的参数

        response.writeHead(200);
        response.write("Hello word!");
        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;

 

 

requestHandler.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,他调用了3个模块,然后声明了一个空的对象,然后给这个对象声明了几个不同的变量(准确的说是函数变量),他们分别对应requestHandlers这个模块的不同函数;

 

调用server这个模块的start方法,传两个参数,分别是router模块的route方法和对象handle(包含3个函数变量);

 

②由于调用了server模块的start方法,因此我们来看server模块;

在server模块中,调用了两个模块,分别是http和url,这两个都是NodeJs自带的,具体里面的内容就不一一分析了(前面已经说明过了)。

 

在servre模块的start函数(也是index.js调用的方法),有两个参数,第一个参数是route函数(来源于router模块),第二个参数是一个对象(来源于index.js)。

 

而在start函数中,调用了其第一个参数(route函数),由于这个参数是函数,因此运行它,给其两个参数,分别是handle(来源于index.js的对象)和pathname(来源于当前模块,是用户请求的路径);

 

因此接下来我们看router模块的route函数,记得,这个函数传递了一个对象和一个路径;

 

③在router模块中,传递了两个参数,并进行了一次判断;

判断的逻辑是这样的,第一个参数(是一个对象),其加上下标后的值,如果是类型是函数,那么执行这个函数;如果不是函数,提示没找到该句柄;

 

请注意,为什么说这个对象加上下标是函数呢,原因在于index中声明的这个对象,而这个对象的三个带下标的变量都是函数;

 

而这三个被执行函数来源于哪呢?来源于index里加载的模块requestHandlers,那么最后让我们来看看这个模块;

 

④在这个模块里,只有两个函数,分别是start和upload;

这两个函数输出不同的内容(一个关键字是start,另一个关键字是upload);

请回想之前的下标,下标分为三个,分别是空(/),start下标(/start),和upload下标(/upload),因此当用户访问根目录、start目录、和upload目录时,调用对应的方法,而若访问其他目录(包括start目录的子目录等时,提示错误——来源于router模块);

现在回顾这种模式是怎么实现的:

 

 

(7)等待函数

function sleep(milliSeconds) {
    var startTime = new Date().getTime();
    while (new Date() < startTime + milliSeconds);  //等待参数的时间
}

 

传的参数是毫秒,在这个时间前,无法执行下一句代码,类似C++的Sleep()函数

 

 

(8)返回的两种格式

response.writeHead(200, {"Content-Type": "text/html"});
response.write(content);
response.end();

 

其中,writeHead里面的第二个参数,有多种格式,分别是:

application/xml 、 text/xml、text/html、text/plain

经查:

text/html是html格式的正文 
text/plain是无格式正文

text/xml忽略xml头所指定编码格式而默认采用us-ascii编码

application/xml会根据xml头指定的编码格式来编码:

简单来说,html就是返回一个html,plain就是无格式的,写什么就是什么,xml就是一个xml文件;

 

 

 

(9)关于事件监听

之前说到有

function onRequest(request, response)

这样一个回调函数,其中request是请求,response是回应;

 

根据推测,每次request的,都会触发至少一个data,一个end事件,因此应该监听这两个事件。(并且只有接受到data之后,才会接收到end事件);

 

我们之前是不监听的,只要有请求,就直接执行某个函数,而监听表示只有这些事件触发后,我们才会执行某一段代码。

 

因此我们这么写:

var postData = "";
request.setEncoding("utf8");
request.addListener("data", function (postDataChunk) {      //data事件
    postData += postDataChunk;
    console.log("Received POST data chunk " + postDataChunk + ".");
    console.log("————————");
})
request.addListener("end", function () {
    route(handle, pathname, response, postData);
})

 

表示监听的编码类型为UTF8,监听data事件,把内容加起来,监听end事件,把加起来的内容发送出去。

 

直到end事件触发时,才会执行之前写的route函数(也就是那个写回复的函数)。

 

 

PS:

①根据我的测试,如果data事件注释掉,end事件会无法执行,准确的说,是无法访问任何url的。

但是,如果不注释掉,只是普通的访问的话,可是又不会触发data监听事件里面的console.log代码,很奇怪;

 

另外,注释掉end事件,留着data事件,也会卡住;

 

时间: 2024-09-09 03:20:52

NodeJs——(1)封装,调用,执行,访问路径,http,函数编程,等待函数,事件监听的相关文章

cocos2d x-cocos如何将事件监听封装到自定义的精灵类中,求一个demo

问题描述 cocos如何将事件监听封装到自定义的精灵类中,求一个demo cocos如何将事件监听封装到自定义的精灵类中,求一个demo.每次创建新的精灵时就会添加触摸监听.在其他层中可以拖拽移动这些添加到层中的精灵 解决方案 把你的方法放进init()里面,继承layer或者node,create()后就会调用.具体的点击事件,你可以百度,很多 解决方案二: 把你的方法放进init()里面,继承layer或者node,create()后就会调用.具体的点击事件,你可以百度,很多 解决方案三:

请问 API 中说的 消息监听 :以上两种方式都可以执行相同的操作,但是广播和监听事件不可同时混用 的 具体意思

问题描述 在同一个 activity 或者appliction 中同时 注册了 两种会怎么样? 同时接受两次?在appliction 中注册了 监听事件, 在 activity 中注册广播 这也是混用?会怎么样? 解决方案 你的项目里只能选择其中一种方式使用,两种混用的话,收到消息之后,广播和监听都不执行

Js事件监听封装(支持匿名函数)

主要代码:  代码如下 复制代码 /*绑定事件与取消绑定*/ var handleHash = {}; var bind = (function() {  if (window.addEventListener) {   return function(el, type, fn, capture) {    el.addEventListener(type, function(){     fn();     handleHash[type] = handleHash[type] || [];

javascript支持匿名函数的事件监听封装

关于js中的事件监听大家用的比较多了,无非是判断浏览器是否支持addEventListener和attachEvent,网上搜索关于事件监听的方法也挺多,但是总有些不是很完善.下面的方法中对于添加事件监听的方法是一样的,只不过在取消事件绑定上面做了点手术,现在可以支持匿名函数的使用,所以在绑定事件的时候不再需要给函数单独命名了. 先看demo:    代码如下 复制代码 <!DOCTYPE html> <html> <head profile="http://www

NodeJS Web应用监听sock文件实例_node.js

像 NodeJS 写的 TCP 服务可以监听在某个 sock 文件(Domain Socket) 上,它的 HTTP 服务也能这么干.虽然作为 HTTP 服务连接某个 sock 文件的意义不大,所以这里只算是一个纯粹的尝试. TCP 服务是这样写 复制代码 代码如下: var net = require('net'); net.createServer(function (socket) {   socket.on('data', function (data) {     socket.wri

nodejs事件的监听与触发的理解分析

 这篇文章主要介绍了nodejs事件的监听与触发的理解分析,以实例形式对比分析了nodejs与jQuery关于事件监听的实用技巧,有助于加深对nodejs的理解,需要的朋友可以参考下     本文实例分析了nodejs事件的监听与触发.分享给大家供大家参考.具体分析如下: 关于nodejs的事件驱动,看了<nodejs深入浅出>还是没看明白(可能写的有点深,或者自己理解能力不够好),今日在图灵社区看到一篇关于nodejs事件的监听与触发,由于给出的例子比较多人,很容易理解,所以也大致明白了no

nodejs事件的监听与触发的理解分析_node.js

本文实例分析了nodejs事件的监听与触发.分享给大家供大家参考.具体分析如下: 关于nodejs的事件驱动,看了<nodejs深入浅出>还是没看明白(可能写的有点深,或者自己理解能力不够好),今日在图灵社区看到一篇关于nodejs事件的监听与触发,由于给出的例子比较多人,很容易理解,所以也大致明白了nodejs事件驱动. 以下内容参考了图灵社区的文章(地址:http://www.ituring.com.cn/article/177478) 首先来了解一下nodejs的Event模块: Nod

Zookeeper 客户端API调用示例(基本使用,增删改查znode数据,监听znode,其它案例,其它网络参考资料)

9.1 基本使用 org.apache.zookeeper.Zookeeper是客户端入口主类,负责建立与server的会话 它提供以下几类主要方法  : 功能 描述 create 在本地目录树中创建一个节点 delete 删除一个节点 exists 测试本地是否存在目标节点 get/set data 从目标节点上读取 / 写数据 get/set ACL 获取 / 设置目标节点访问控制列表信息 get children 检索一个子节点上的列表 sync 等待要被传送的数据            

java做了一个exe程序怎么通过监听返回运行程序的路径

问题描述 java做了一个exe程序怎么通过监听返回运行程序的路径 用java写了个程序,想实现开机启动的功能,方法是想写入注册表,但是我要怎么知道我打开的这个程序的路径,就是我要通过监听,然后程序打开开机启动功能怎么返回该程序的路径,明白我的意思吗,或者有其他方法也可以? 解决方案 可以通过两种方式解决: 1.String path = new File(".").getCanonicalPath(); 2.System.getProperty("user.dir"