同步与异步的区别

本文深入探讨了JavaScript中的同步与异步执行机制,包括宏任务与微任务的执行顺序。通过示例代码阐述了同步代码如何直接进入执行栈,而异步代码则在完成后进入任务队列。强调了异步执行对于Node.js的事件驱动和无阻塞特性的重要性,特别是在文件I/O操作中的应用。同步代码可能导致主线程阻塞,影响服务可用性,而异步处理则能保持服务的高效运行。
摘要由CSDN通过智能技术生成

同步与异步的区别

同步代码: js为脚本语言,对于同步代码来说,自上而下进行解释执行

异步代码: 对于一个任务,分为多个片段来进行执行, 先执行一段,如果碰到比较耗时间的操作,比如本地或者网络io请求。
第一段开始进行io之后,把执行权交由其他任务,当io完成后再来执行后半段的任务(io操作比较耗时,在系统进行io时,主线程是空闲的)

console.log('sync1') // 同步任务
setTimeout( // 宏任务
    () => {
        console.log('timerout')
    },
    0
)
Promise.resolve().then(() => { // 微任务
    console.log('promise1')
    return 1
}).then(() => {
    console.log('promise 2')
})
console.log('sync2') // 同步任务

对于上面的代码来说, 结果会是

在这里插入图片描述

上面的代码的执行顺序为,当主线成自上而下执行的时候, 会把同步代码直接加入执行栈,对于异步的setTimeout,promise。

会调用api来执行,当任务执行完成的时候。在任务队列里注册事件,把回调函数放入任务队列。当主线程执行完成执行栈之后,会扫描任务队列,看有那些事件,有那些回调任务需要执行,把这些任务放入执行栈由主线程执行。
当主线程执行完成之后继续扫描任务队列。这是个无限的循环,直到任务队列为空,主线程也就进入了空闲状态

异步任务又分成宏任务和微任务
宏任务: setTimeout, setInterval, UI rending, 回调函数, setImmediate(node)等
微任务: Promise, MutationObserver, process.nextTick(node)

异步任务的执行顺序是,同步代码块 -> 微任务 -> 宏任务
也有一种理解方式是把同步代码块当成宏任务的一部分。

由此可以总结
同步代码快会直接进入执行栈,而异步代码会先在完成之后进入任务队列,当执行栈为空之后扫描入栈。由主线程执行

回想一下我们node.js的两个特性

  1. 事件驱动
  2. 无阻塞

考虑以下的代码

const fs = require('fs')
fs.readFile('FilePath', (err, data) => {
    if (err) throw err
    response.write(data)
    response.end()
})

这时代码是异步的,当文件io发生时,主线程可以继续接受连接请求、处理请求

当代码是同步的时候

try {
    const data = fs.readFileSync('FilePath')
    response.write(data)
    response.end()
} catch (e) {
    throw(e)
}

此时主线程在文件io执行完成之间是阻塞的,也就是在这个时间段内。我们的node服务是不可用的。如果在浏览器上表现的就是浏览器html页面完全卡死。这在体验上是不可接受的

由此我们可以得出异步跟同步的第二个区别: 无阻塞

至此我们得出了同步代码与异步代码的两个不同,一个是执行的时间机制,同步要先于异步(也可以理解宏任务先执行); 另一个就是对主线程的阻塞。

对于异步任务的执行,js采用的是线程池的方式,在node端使用libuv,有libuv的work thread来执行异步任务,并在libuv中维护任务队列
在客户端中则是由浏览器来扮演这个角色

欢迎指正,共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值