专业编程基础技术教程

网站首页 > 基础教程 正文

nodejs入门教程之同步与异步(八) nodejs入门基础教程

ccvgpt 2024-10-12 15:07:22 基础教程 14 ℃


学习背景

上个章节我们学习了文件系统fs,我提到了fs提供的api中同时包含了同步方法和异步方法。那有些人就好奇了,为啥要同时提供这两种类型的api呢,一个同步的方法不就够了吗?同步方法不是更好用吗?同步方法和异步方法又有啥区别呢?那我们这篇文章就好好好说道说道这个同步与异步。

nodejs入门教程之同步与异步(八) nodejs入门基础教程

同步与异步的含义

那什么是同步什么是异步呢?

  • 同步:线程调度所有资源集中处理该任务,因此在执行该任务时,其他任务会被暂停,直到该同步任务执行完毕。
  • 异步:线程调度部分资源处理该任务,不会暂停其他任务。可以和其他任务一起执行。

光这么说你可能还不是很理解,我举个例子。就拿我们常见的外卖员来说,外卖员接单送外卖通常是一次接多单一起配送的。同步等于每次只接一单,等这一单送完了,然后再抢下一单配送。异步等于每次抢多单,然后多单一起配送。我们使用上个章节中fs读取文件的方法来实现一下。fs读取文件方法分为同步方法(fs.readFileSync)和异步方法(fs.readFile),我们在读取文件的同时,定一个定时任务,让他定时的打印数据出来

同步实现

代码

// 同步测试
// 同步测试
function tongbuTest() {
    const itl = setInterval(() => {
        console.log('task do...')
    }, 0)
    console.log('开始读取文件')
    console.time('读取文件')
    const data = fs.readFileSync(path.join(__dirname, 'file/pexels-daniel-torobekov-5694144.jpg'));
    console.timeEnd('读取文件')
    console.log('读取文件结束')
}

执行结果


结论

从打印的结果我们可以看出,读取文件花了4.393毫秒,在执行读取文件的时候,定时任务并没有执行,直到文件读取完毕后定时任务才开始执行。说明在进行同步读取文件的时候,线程集中了所有资源去处理该任务,把其他任务暂停了,因而它读取文件任务执行的比较快。

异步实现

代码

// 异步测试
function yibuTest() {
    const itl = setInterval(() => {
        console.log('task do...')
    }, 0)
    console.time('读取文件')
    fs.readFile(path.join(__dirname, 'file/pexels-daniel-torobekov-5694144.jpg'), () => {
        console.timeEnd('读取文件')
    });
}

执行结果

结论

从打印的结果我们可以看出,读取文件花了7.708毫秒,在执行读取文件任务的时候定时任务也在执行。说明在进行异步读取文件的时候,线程没有像同步任务一样暂停了其他任务的执行,而是和其他任务一起执行的。因为没有调度所有资源进行来执行读取文件,所以它读取的时间响应的会慢一点(案例中有偶然性,可以做多次测试来验证)。

同步与异步的优缺点

上面我用派送外卖来举例了同步和异步,同步就是一次接一单派送一单,异步是一次接多单,一起派送。一次接一单派送的话每一单送达的时间就会快很多,但是一天内能够完成的订单就比较少。一次接多单派送虽然每一单的时间会略久一点,但是他一天可以派送的订单就会大大的增多,这样也就提高了派送员的收入。同步和异步也是这个道理,同步执行任务的话,每个任务执行的速度快,但是多任务的时候效率就比较慢。异步执行的话虽然每个任务可能会相应的慢一点,但是在执行多个任务的时候,效率往往会高很多。所以nodejs建议使用异步来调度任务。

异步与多线程

异步和多线程是两个概念,我还是拿前面的外卖派送来说,一次一单是同步,一次多单是异步,那么多线程等于分配多个外卖配送员。那么每个外卖员都是一个线程,每个线程都可以采取同步还是异步配送。仔细想想是不是多线程更加牛逼啊,它可以更大程度的提高效率。但是多线程是建立在资源非常丰富的情况下的,就像配送站很有钱,可以招聘很多的配送员。但是了解nodejs基础的应该知道,nodejs是单线程的。所以在这个单线程中,如果使用了同步方法就会把当前线程给卡死了,比如我们去读取一个超大的文件,那么在读取过程中,我们的程序就等于完全暂停了。但是如果nodejs有多线程,那么使用同步任务的话可以通过分配多个线程来实现并发执行。这一点可以参考java,java就是同步任务多线程模型,通过多线程来解决线程阻塞问题,但是每分配一个线程必定会增加电脑的负担,可用的线程也是有限的。所以java也会引入异步IO,当然这是后话了。nodejs也会引入多线程,这也是后话了哈哈,后面有机会可以再详细介绍一下。

最后

通过这章学习我们应该对同步异步有了初步的了解,后期nodejs学习中,我们会大量接触同步与异步函数,那时候我们会详细学习每个同步异步函数用法。还有就是异步的实现方案callback回调以及promise,这两个知识点我将在下一个章节讲一讲。最后本章节涉及的代码,你可以通过访问GITHUB代码仓库下载。

Tags:

最近发表
标签列表