同步和异步
学习 Node.js 异步编程前,首先我们来了解一下什么是同步,什么是异步。
同步
首先举一个简单的例子来说明同步的概念。比如有一家小吃店,只有一名服务员叫小王,这天中午,来了很多客人,小王需要为客人下单和送餐。那么,小王如果采用同步方法,效果如图9.1所示。

Figure 1. 图9.1 小王采用同步方法
小王首先为顾客 1 服务,将顾客下的单给到厨房,等待餐做好后送餐给顾客。服务完顾客1后,再按照同样的步骤服务顾客2、顾客3……使用这种方法,在服务完顾客1之前,顾客2和顾客3只能是一直等待,显然效率非常低。如果使用代码来模拟上面的场景,则代码如下:
//同步方法
console.log("小王为顾客1下单。")
console.log("小王为顾客1送餐。")
console.log("小王为顾客2下单。")
console.log("小王为顾客2送餐。")
console.log("小王为顾客3下单。")
console.log("小王为顾客3送餐。")
运行上面代码,效果如图9.2所示。

Figure 2. 图9.2 小王使用同步方法为顾客服务
异步
同样是上面的例子,小王如果采用异步方法,则其为顾客服务的示意图如图9.3所示。

Figure 3. 图9.3 小王采用异步方法
小王可以分别将顾客1、顾客2和顾客3下的单给到厨房,待厨房陆续做好时,小王再分别为顾客1、顾客2和顾客3送餐,这就是采用了异步的方法,与同步方法相比,这样做的效率显然会大大提升。如果用代码来模拟上面的场景,则代码如下:
//异步方法
console.log("小王开始为顾客服务。");
//送餐服务
Function service(){
//setTimeout代码执行时,不会阻塞后面的代码执行
setTimeout(function () {
console.log("小王为顾客1送餐。");
},0);
setTimeout(function () {
console.log("小王为顾客2送餐。");
},0);
setTimeout(function () {
console.log("小王为顾客3送餐。");
},0);
}
console.log("小王为顾客1下单。");
service();
console.log("小王为顾客2下单。");
console.log("小王为顾客3下单。");
运行上面代码,效果如图9.4所示。

Figure 4. 图9.4 小王使用异步方法为顾客服务
对比小王使用同步方法和异步方法为顾客服务的过程,可以很明显地看到,在异步模式下的服务更加人性化,用户体验更好。Node.js 中同样提供了异步编程模式,Node.js 中的异步编程主要通过回调函数或者 async/await
实现,下面分别进行讲解。