对于node.js还是由于项目需要,第一次接触是在一个月前,作为一个前端,我本身对js还是比较了解的,但是对于node(下文中所有的node都指node.js)的一切却是一无所知,于是开始上官网去看文档,官网地址www.nodejs.org,不过都是英文的,看起来太吃力了!所以最后还是去百度了!
首先跟大部分初学者一样,开始安装node.js,我使用的是linux下的版本;至于安装过程网上一大堆,我在这里就不多做赘述了,有兴趣的自己去搜搜看。
和很多人一样,一开始看到的都是官网首页的一个关于在页面输出"Hello World"的例子:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
其实现在明白:这其实是在创建一个http请求监听,在接受到浏览器的请求之后,返回"Hello World"!其参数req为请求的内容,res为返回的结果!至于1337为服务器端口,127.0.0.1是服务器ip地址!
我在先试验完这个例子以后,感觉对node.js还是一无所知,奈何有看不懂英文,只能先去百度一下,node.js到底是什么?它是如何工作的?
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台, 用来方便地搭建快速的 易于扩展的网络应用·Node.js 借助事件驱动, 非阻塞I/O 模型变得轻量和高效, 非常适合 运行在分布式设备 的 数据密集型 的实时应用--摘自百度百科
这里需要注意的是,js是基于事件驱动的异步语言,这对于我这个很少接触异步的人来说,写起程序来还是给我带来了不少麻烦!
在了解了定义和用法之后,接下来就开始真正的去使用它了。首先,node采用的是模块机制,在需要的时候引入需要的模块就可以了(当然你必须依据安装了该模块才行):
var http = require("http");//引入http模块
require()为引入模块方法,其接收一个模块路径标识为参数,即模块的相对路径!
好了,这样我们就可以使用http模块了:
//监听http请求,并将接收到的内容打印出来 http.createServer(function (req, res) { console.log(req); res.end(); }).listen(port, host);
关于node的模块分为两种:一种是node提供的核心模块,一种是用户自己编写的文件模块;
node模块的引入需要经历:路径分析-->文件定位-->编译执行。3个步骤!而且引入模块的时候扩展名可以不写,他们可以是.js,.node,.json或者是其他扩展名!当然,如果在引入时不写扩展名,require()方法会按照.js、.node、.json的次序来补足扩展名!当我们想把自己定义的方法当作模块引入时,需要在文件里将方法绑定在exports上:
//创建一个名为tool的js文件,里面内容如下: exports.setObjVal = function( obj, obj2 ) { for( p in obj ) { obj[p] = obj2[p]; } return obj; }
我在tool.js里定义了一个把对象2中属性的值赋给对象1中同名属性的函数setObjVal(),并且把它绑定在exports上,那么我在跟tool.js同文件夹下的另一个js文件start.js中就可以通过require()方法引入tool.js并使用setObjVal()函数了:
var tool = require("./tool"), o1 = { name:"小明", age :"18" }, o2 = { name:"小王", age :"20" }; tool.setObjVal(o1, o2); console.log(o1.name);//输出:小明
通过上面的例子,我想大家对于模块引入应该会有个大概的了解了!好,接下来我们来说说nodejs的异步!
同步:所谓同步传输是指数据块与数据块之间的时间间隔是固定的,必须严格地规定它们的时间关系。
异步:所谓异步传输是指字符与字符(一个字符结束到下一个字符开始)之间的时间间隔是可变的,并不需要严格地限制它们的时间关系。
其实说的明白点同步和异步的区别就在于同步需要等待请求的返回值会来后在执行下一段程序,而异步却不需要,它会在发出请求后不管请求有没有返回,都会立即执行下一段程序!
//下面是发送请求并发送邮件 //加载http模块 var http = require("http"); //设置请求参数 var options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET'' } //发送请求,并打印返回的数据内容 var req = http.request(options, function(res) { res.setEncoding('UTF-8'); res.on('data', function (data) { console.log(data); }) }); //加载邮件模块 var nodemailer = require("nodemailer"); //设置发送参数 var smtpTransport = nodemailer.createTransport("SMTP", { host: "smtp.qq.com", secureConnection: true, port: 465, auth :{ user: "282729573@qq.com", pass: "0000000" } }); //设置邮件参数 var mailOptions = { to: "12345678@qq.com", subject: "你好!", html: "欢迎浏览平凡公子的文章" } //发送邮件和错误处理 smtpTransport.sendMail(mailOptions, function(error, response) { if(error) { console.log('邮件'+error); } else { console.log(response.message); } smtpTransport.close(); });
以上代码如果是同步执行的话,那么在发送请求后,必须要等到接收到返回值后才会执行发送邮件的部分,但是,由于node的异步,那么在发送请求后,不管数据是否接收到,都会立刻紧接着执行下面发送邮件的代码!这就是异步!
当然异步有很多好处,但是像我这样没怎么接触过异步的人,刚开始用异步语言编程无疑是非常痛苦的,这些痛苦主要来自于对于程序流程的控制上!以前都是发个请求,得到数据,然后执行下一步操作,但是现在不一样了,异步中,发出请求后,要想在得到数据后在执行下一步,就需要不下一步的代码写在请求的回调函数里,这样一层套一层的,才能确保我们的程序能够正确的运行下去,但是这又会导致一个问题:嵌套过深!
嵌套过深当然不会对你的程序正确性上有什么太大的影响,但是这样会大大的降低代码的可读性,和可维护行,并且还很不美观!这对于那些有点小强迫症的程序员来说绝对是无法容忍的,所以为了避免这个问题(当然现在已经有node.js的框架已经能很好的解决了)不爱用框架的我一般采用将回调函数单独出来的方法:
//加载文件模块 var fs = require("fs"), //创建阅读配置文件方法 readFile = function (callback){ //读取配置文件,参数分别为:文件路径,编码,回调函数 fs.readFile('./config.json', 'utf-8', function (err, data) { if (err) throw err;//错误处理 callback(data); //调用readFile()函数的回调函数 }); //创建readFile()函数的回调函数,并处理数据且打印出数据 function callback(res){ var r = JSON.parse(res); console.log(r.host) } } //调用readFile()函数 readFile();
将回调函数独立出来至少在维护和美观上还是有很大改变的!
虽然node.js作为服务器端语言,在很多方面都与前端js有很大不同,但是最少在语法上,语言风格上和内置方法上都还是一样的,所以对于熟悉js的人,相信也能很快上手node.js的!虽然我在初步接触到真正去写项目到项目完成一共只有不到一个月时间,但是对于node的一些基本用法及特性还是了解了一点!所以在这里把自己经历的和理解的写出来跟大家分享一下,同时也作为自己的一个学习笔记,方便自己以后查看!当然,由于接触时间不长,了解有限,掌握不深等原因,可能所说并不是十分正确,如果哪位同学看到错误的地方还请指正,谢谢大家!
本文由 平凡公子原创并首发于其个人博客(转载请注明作者及原文地址)欢迎阅读!