同步和异步

学习 Node.js 异步编程前,首先我们来了解一下什么是同步,什么是异步。

同步

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

image 2024 04 13 20 28 59 711
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所示。

image 2024 04 13 20 30 07 420
Figure 2. 图9.2 小王使用同步方法为顾客服务

异步

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

image 2024 04 13 20 31 40 969
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所示。

image 2024 04 13 20 34 25 426
Figure 4. 图9.4 小王使用异步方法为顾客服务

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