您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 工程监理 > NodeJs教程_JavaScript标准参考教程
Node.js概述目录简介安装与更新版本管理工具nvm基本用法REPL环境异步操作全局对象和全局变量模块化结构概述核心模块自定义模块http模块基本用法处理POST请求发出请求:get方法发出请求:request方法搭建HTTPs服务器模块属性模块方法Buffer对象异常处理try...catch结构uncaughtException事件正确的编码习惯命令行脚本参考链接简介Node是JavaScript语言的服务器运行环境。所谓“运行环境”有两层意思:首先,JavaScript语言通过Node在服务器运行,在这个意义上,Node有点像JavaScript虚拟机;其次,Node提供大量工具库,使得JavaScript语言与操作系统互动(比如读写文件、新建子进程),在这个意义上,Node又是JavaScript的工具库。Node内部采用Google公司的V8引擎,作为JavaScript语言解释器;通过自行开发的libuv库,调用操作系统资源。安装与更新访问官方网站nodejs.org了解安装细节。安装完成以后,运行下面的命令,查看是否能正常运行。$node--version#或者$node-v更新node.js版本,可以通过node.js的n模块完成。$sudonpminstalln-g$sudonstable上面代码通过n模块,将node.js更新为最新发布的稳定版。n模块也可以指定安装特定版本的node。$sudon0.10.21版本管理工具nvm如果想在同一台机器,同时安装多个版本的node.js,就需要用到版本管理工具nvm。$gitclone~/.nvm$source~/.nvm/nvm.sh安装以后,nvm的执行脚本,每次使用前都要激活,建议将其加入~/.bashrc文件(假定使用Bash)。激活后,就可以安装指定版本的Node。#安装最新版本$nvminstallnode#安装指定版本$nvminstall0.12.1#使用已安装的最新版本$nvmusenode#使用指定版本的node$nvmuse0.12nvm也允许进入指定版本的REPL环境。$nvmrun0.12如果在项目根目录下新建一个.nvmrc文件,将版本号写入其中,就只输入nvmuse命令即可,不再需要附加版本号。下面是其他经常用到的命令。#查看本地安装的所有版本$nvmls#查看服务器上所有可供安装的版本。$nvmls-remote#退出已经激活的nvm,使用deactivate命令。$nvmdeactivate基本用法安装完成后,运行node.js程序,就是使用node命令读取JavaScript脚本。假定当前目录有一个demo.js的脚本文件,运行时这样写。nodedemo//或者nodedemo.jsREPL环境在命令行键入node命令,后面没有文件名,就进入一个Node.js的REPL环境(Read–eval–printloop,读取-求值-输出循环),可以直接运行各种JavaScript命令。$node1+12如果使用参数--use_strict,则REPL将在严格模式下运行。$node--use_strictREPL是Node.js与用户互动的shell,各种基本的shell功能都可以在里面使用,比如使用上下方向键遍历曾经使用过的命令。特殊变量下划线(_)表示上一个命令的返回结果。1+12_+13在REPL中,如果运行一个表达式,会直接在命令行返回结果。如果运行一条语句,就不会有任何输出,因为语句没有返回值。x=11varx=1上面代码的第二条命令,没有显示任何结果。因为这是一条语句,不是表达式,所以没有返回值。异步操作Node采用V8引擎处理JavaScript脚本,最大特点就是单线程运行,一次只能运行一个任务。这导致Node大量采用异步操作(asynchronousopertion),即任务不是马上执行,而是插在任务队列的尾部,等到前面的任务运行完后再执行。由于这种特性,某一个任务的后续操作,往往采用回调函数(callback)的形式进行定义。varisTrue=function(value,callback){if(value===true){callback(null,Valuewastrue.);}else{callback(newError(Valueisnottrue!));}}上面代码就把进一步的处理,交给回调函数callback。Node约定,如果某个函数需要回调函数作为参数,则回调函数是最后一个参数。另外,回调函数本身的第一个参数,约定为上一步传入的错误对象。varcallback=function(error,value){if(error){returnconsole.log(error);}console.log(value);}上面代码中,callback的第一个参数是Error对象,第二个参数才是真正的数据参数。这是因为回调函数主要用于异步操作,当回调函数运行时,前期的操作早结束了,错误的执行栈早就不存在了,传统的错误捕捉机制try...catch对于异步操作行不通,所以只能把错误交给回调函数处理。try{db.User.get(userId,function(err,user){if(err){throwerr}//...})}catch(e){console.log(‘Ohno!’);}上面代码中,db.User.get方法是一个异步操作,等到抛出错误时,可能它所在的try...catch代码块早就运行结束了,这会导致错误无法被捕捉。所以,Node统一规定,一旦异步操作发生错误,就把错误对象传递到回调函数。如果没有发生错误,回调函数的第一个参数就传入null。这种写法有一个很大的好处,就是说只要判断回调函数的第一个参数,就知道有没有出错,如果不是null,就肯定出错了。另外,这样还可以层层传递错误。if(err){//除了放过NoPermission错误意外,其他错误传给下一个回调函数if(!err.noPermission){returnnext(err);}}全局对象和全局变量Node提供以下几个全局对象,它们是所有模块都可以调用的。global:表示Node所在的全局环境,类似于浏览器的window对象。需要注意的是,如果在浏览器中声明一个全局变量,实际上是声明了一个全局对象的属性,比如varx=1等同于设置window.x=1,但是Node不是这样,至少在模块中不是这样(REPL环境的行为与浏览器一致)。在模块文件中,声明varx=1,该变量不是global对象的属性,global.x等于undefined。这是因为模块的全局变量都是该模块私有的,其他模块无法取到。process:该对象表示Node所处的当前进程,允许开发者与该进程互动。console:指向Node内置的console模块,提供命令行环境中的标准输入、标准输出功能。Node还提供一些全局函数。setTimeout():用于在指定毫秒之后,运行回调函数。实际的调用间隔,还取决于系统因素。间隔的毫秒数在1毫秒到2,147,483,647毫秒(约24.8天)之间。如果超过这个范围,会被自动改为1毫秒。该方法返回一个整数,代表这个新建定时器的编号。clearTimeout():用于终止一个setTimeout方法新建的定时器。setInterval():用于每隔一定毫秒调用回调函数。由于系统因素,可能无法保证每次调用之间正好间隔指定的毫秒数,但只会多于这个间隔,而不会少于它。指定的毫秒数必须是1到2,147,483,647(大约24.8天)之间的整数,如果超过这个范围,会被自动改为1毫秒。该方法返回一个整数,代表这个新建定时器的编号。clearInterval():终止一个用setInterval方法新建的定时器。require():用于加载模块。Buffer():用于操作二进制数据。Node提供两个全局变量,都以两个下划线开头。_filename:指向当前运行的脚本文件名。_dirname:指向当前运行的脚本所在的目录。除此之外,还有一些对象实际上是模块内部的局部变量,指向的对象根据模块不同而不同,但是所有模块都适用,可以看作是伪全局变量,主要为module,module.exports,exports等。模块化结构概述Node.js采用模块化结构,按照CommonJS规范定义和使用模块。模块与文件是一一对应关系,即加载一个模块,实际上就是加载对应的一个模块文件。require命令用于指定加载模块,加载时可以省略脚本文件的后缀名。varcircle=require('./circle.js');//或者varcircle=require('./circle');require方法的参数是模块文件的名字。它分成两种情况,第一种情况是参数中含有文件路径(比如上例),这时路径是相对于当前脚本所在的目录,第二种情况是参数中不含有文件路径,这时Node到模块的安装目录,去寻找已安装的模块(比如下例)。varbar=require('bar');有时候,一个模块本身就是一个目录,目录中包含多个文件。这时候,Node在package.json文件中,寻找main属性所指明的模块入口文件。{name:bar,main:./lib/bar.js}上面代码中,模块的启动文件为lib子目录下的bar.js。当使用require('bar')命令加载该模块时,实际上加载的是./node_modules/bar/lib/bar.js文件。下面写法会起到同样效果。varbar=require('bar/lib/bar.js')如果模块目录中没有package.json文件,node.js会尝试在模块目录中寻找index.js或index.node文件进行加载。模块一旦被加载以后,就会被系统缓存。如果第二次还加载该模块,则会返回缓存中的版本,这意味着模块实际上只会执行一次。如果希望模块执行多次,则可以让模块返回一个函数,然后多次调用该函数。核心模块如果只是在服务器运行JavaScript代码,用处并不大,因为服务器脚本语言已经有很多种了。Node.js的用处在于,它本身还提供了一系列功能模块,与操作系统互动。这些核心的功能模块,不用安装就可以使用,下面是它们的清单。http:提供HTTP服务器功能。url:解析URL。fs:与文件系统交互。querystring:解析URL的查询字符串。child_process:新建子进程。util:提供一系列实用小工具。path:处理文件路径。crypto:提供加密和解密功能,基本上是对OpenSSL的包装。上面这些核心模块,源码都在Node的lib子目录中。为了提高运行速度,它们安装时都会被编译成二进制文件。核心模块总是最优先加载的。如果你自己写了一个HTTP模块,require('http')加载的还是核心模块。自定义模块Node模块采用CommonJS规范。只要符合这个规范,就可以自定义模块。下面是一个最简单的模块,假定新建一个foo.js文件,写入以下内容。//foo.jsmodule.exports=function(x){console.log(x);};上面代码就是一个模块,它通过module.exports变量,对外输出一个方法。这个模块的使用方法如下。//index.jsvarm=require('./foo');m(这是自定义模块);上面代码通过require命令加载模块文件foo.js(后缀名省略),将模块的对外接口输出到变量m,然后调用m。这时,在命令行下运行index.js,屏幕上就会输出“这是自定义模块”。$nodeindex这是自定义模块module变量是整个模块文件的顶层变量,它的exports属性就
本文标题:NodeJs教程_JavaScript标准参考教程
链接地址:https://www.777doc.com/doc-2889787 .html