您的位置:首页 >> LNMPA >> 和屌丝一起学Node.js—异步
和屌丝一起学Node.js—异步
[ 孤狼 | 2017-08-14 16:45:47 | LNMPA ]
声  明

本教程仅用于初学Node.js同学使用,内容由本人(孤狼)学习过程中笔记编写,本教程使用Node.js版本为6.11.1。本教程内容可以自由转载,但必须同时附带本声明,或注明出处。PAEA.CN版权所有。

上节我们说了如何用Node.js来做个HTTP服务器,但是我们还没有了解Node.js的运行模式,这节我们将一起来看看Node.js的主运行模式-异步


很多时候都说Node.js运行很快,为什么快呢,那是因为Node.js的主要运行模式就是异步运行,所以大多数时间不会出现等待的情况.(具体异步和同步的区别这里就不在赘述,你也可以看下面的例子来理解.)


这里我们做个测试,看看Node.js的运行方式.

新建一个test.js文件.

输入代码:

//方法a:
function a(){
	console.log("我是A");
}
//方法b:
function b(){
	console.log("我是B");
}
a();
b();


这里,我们按照以往(同步运行)思维的想法来看,运行的结果应该是"我是A我是B",因为先调用了a后调用了b.

1.jpg

运行的结果也证实了,确实是这么回事.那么这样和异步有什么区别呢?区别在于,遇到Node.js的异步方法的时候.

换句话说,如果你的程序中都是这样自定义的函数在跑,那么和顺序执行(同步运行)没有区别,区别仅仅发生在遇到异步方法时.


但是这种处理无需等待的情况在真实运行环境中很少,真实环境中,我们的服务器往往还要去连接数据库,读取数据库,然后再获取数据,之后才能进行数据处理,这样的话,我们中间都是有很长时间的等待的.而以往的运行方式(同步),是上一步不执行完,下一步不会开始.这会使得我们的访问时间变长.而Node.js中很多这样的处理都是异步运行,也就是,如果上一步拖拉时间,下一步是不会等待的.后面的程序会立即执行.

我们再看一个例子:

//方法a:
function a(){
	const fs = require('fs');//调用文件系统模块
	fs.writeFile('./1.txt',"哈哈哈哈",()=>{//写入"哈哈哈哈"到脚本目录下的1.txt文件中.
		console.log("我是A");
	});
}
//方法b:
function b(){
	console.log("我是B");
}
a();
b();

2.jpg

这里我们可以看到,输出的结果是"我是B,我是A",先调用的a却后输出.这是应为fs模块的writeFile采用异步执行,当然你也可以使用对应的writeFileSync同步方法.但是这里并不推荐,因为有不少方法并没有对应的同步方法.


既然系统里很多是异步的,那么当我们想用同步的时候怎么办?

一个是可以使用对应的同步方法,还有一个就是采用回调的方式.因为异步也要先执行后回调.所以把需要严格放在后面的代码放在回调里.

例如下面这个错误案例:

//方法a:
function a(){
	const fs = require('fs');//调用文件系统模块
	fs.writeFile('./1.txt',"哈哈哈哈",()=>{//写入"哈哈哈哈"到脚本目录下的1.txt文件中.
		console.log("创建文件1.txt完成");
	});
	//读取文件
	console.log("读取文件1.txt....");
}
//方法b:
function b(){
	console.log("我是干扰项B");
}
a();
b();


3.jpg

我们看到由于writeFile的异步操作,导致先读取文件,后创建文件,这不是我们希望得到的结果.所以我们对代码进行一点小修改,把读取文件放在创建文件的回调里.

//方法a:
function a(){
	const fs = require('fs');//调用文件系统模块
	fs.writeFile('./1.txt',"哈哈哈哈",()=>{//写入"哈哈哈哈"到脚本目录下的1.txt文件中.
		console.log("创建文件1.txt完成");
		//读取文件
		console.log("读取文件1.txt....");
	});
}
//方法b:
function b(){
	console.log("我是干扰项B");
}
a();
b();


4.jpg

这里我们看到,方法a虽然还是异步运行到了方法b后面结束,但是a的内部是同步(顺序)执行的,符合我们的预期.


本节代码下载:链接: https://pan.baidu.com/s/1sl39Xwx 密码: 46du

转载请注明出处:http://gl.paea.cn/lnmpa/content/2017/08/14/108.html