谈谈你是如何理解 JS 异步编程的?Event Loop、消息队列都是做什么的?什么是宏任务?什么是微任务?

1. JS 为什么需要异步编程?
  首先,我们都知道 JS 的执行环境是单线程的,而单线程的目的是为了避免对浏览器 DOM 的混乱操作,比如说,现在有两个线程,线程 A 执行删除 DOM 元素1操作,线程 B 则执行修改 DOM 元素1操作,如果代码是多线程的,两个线程同时执行操作,结果将不会知道到底是删除,还是修改了 DOM 元素,故而 JS 是单线程的。
  而单线程意味着代码的执行顺序是固定的,从上到下依次执行,那当程序遇到耗时的操作,就会形成阻塞,甚至导致浏览器界面假死。此时异步便很重要了,故而 JS 提供了同步和异步两种模式。

同步模式:单线程。代码从上到下一次执行,下一个任务等待上一个任务结束后执行。
异步模式:多线程。任务执行开始与上一个任务的执行结束无关,可以认为是同时执行,每个任务有一个或多个回调函数,任务执行结束后执行回调函数。即程序的执行顺序与任务的排列顺序不同。

2. JS 异步编程过程
异步编程过程
  当 JS 主线程发起异步调用,JavaScript 线程与异步调用线程同时执行,JavaScript 线程的任务会被压入调用栈中,而异步任务执行完成后,会被压入消息队列中,当 JavaScript 线程任务执行完成,即调用栈为空时,Event Loop 会将消息队列中的回调任务从头到尾依次压入调用栈并执行。

Event Loop(消息线程): 是一个程序结构,用于等待和发送消息和事件。负责监听调用栈和消息队列,一旦调用栈清空,则将消息队列的任务压入调用栈。
Queue(消息队列):用于处理异步编程。当存在异步任务时,便压入消息队列中,执行完毕后再由任务队列通知主线程,让JS 引擎接管此事件。

3. 宏任务 VS 微任务

宏任务:每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。
微任务:在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。
执行顺序:
    1)执行一个宏任务(栈中没有就从事件队列中获取)
    2)执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
    3)宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
    4)当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
    5)渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)

宏任务微任务
包含script(整体代码)
setTimeout setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)
Promise.then
Object.observe(已废弃;Proxy 对象替代)
MutationObserver
process.nextTick(Node.js 环境)
谁发起的宿主(Node、浏览器)JS引擎
谁先运行后运行先运行
会触发新一轮Tick吗不会

参考文章

JavaScript 异步编程的4种方法
什么是 Event Loop?
JS 中的宏任务与微任务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值