最简单的大白话给你说明白js的异步机制

270 阅读4分钟

小葵花课堂又开课了惊不惊喜,意不意外,今天扯扯js的异步机制,这个异步机制,就像藏在面纱后面的大姑娘,扯下面纱那一刹那定眼一看也就那么回事,只要用心看一下,这玩意简单的不能再简单,我希望能用最简单的话给大伙描述明白它到底是个咋鸡儿回事

按照国际惯例还是要提出问题,有了问题才更好理解:

  1. 啥叫异步
  2. 为啥要异步
  3. 为啥要了解异步机制

有点基础的都知道js单线程,异步可以防止阻塞,基础问题就不多赘述了,重点就是我们为啥要了解异步机制,个人认为有两个方面:

  • 一是在平常写代码时候容易碰到一些执行顺序的坑,虽说一般不会引起什么太大问题,但是当程序复杂庞大后,一旦有因为程序执行顺序引起的问题很难被发现。
  • 二是我们在做性能优化时有可能会用到相关知识,毕竟微任务要比宏任务执行的快点,,类似这些鸡毛蒜皮的破事,日常开发中大家都家大业大的谁会在乎这点性能。如果你要写个牛逼的库或插件那这事你就得深入研究研究了“钱”也还都是省出来的。

啊扯那去了,我都不知道我要写啥了,唱首歌压压惊

js的异步实现得分两个方向来说,一个是浏览器的实现,另一个是node.js的实现 我们先说浏览器的:

说之前插播点题外话,这里边有两个概念,大学时候学过数据结构的很好理解,就是 栈 ,队列,栈遵从先进后出的原则,队列可以理解成排队,不懂的我们就不去纠结他是啥,就记住这俩名字就成,就当是两个容器

  • Row No.1 代码在栈里依次执行
  • Row No.2 碰到异步代码执行,将回调放在队列中
  • Row No.3 浏览器会有个循环,栈里的代码执行完了将队列中代码都拿出来放入栈里在执行

我都懒得画图,就这么简单,上面过程不停循环,就是浏览器的异步机制Event Loop! 执行完同步代码,将异步执行完的回调代码拿出来放到栈在依次执行一遍!不停的循环这个过程,直到js代码全部执行完!
后来这里面插入了微任务的概念,意思就是说,有些东西我不想马上执行,但是也不想排在异步队列后面,就是执行完当前同步代码,马上就执行这个任务,这就叫微任务,任务存在微任务队列里,那相对的原先那个异步队列就叫宏任务

微任务是每次执行完同步代码立即就执行微任务,然后再去检索宏任务去执行

浏览器在执行完同步代码后,并不会马上就执行异步队列,二是去渲染js中对dom的操作,然后回头在执行异步队列

然而Node的事件环和浏览器有啥区别呢?下图是个node事件环模型

看图虽然复杂,但是我们只需要关心timers计时器阶段,poll轮询阶段,check检查阶段(setImmediate回掉),clons关闭阶段以及微任务队列即可,因为处理网络,内部调用与咱们的宏任务和微任务的执行没有太大的关系 和浏览器运行环境不同的是微任务只会在阶段转化的时候才会调用,就是close关闭阶段后再执行下一阶段的时候 如果宏任务执行的时候又发现微任务了,不会和浏览器一样顺便执行了,而是会将微任务再放到微任务队列中,等待整个阶段结束后,下一个阶段开始的时候先执行完微任务队列中的微任务

就这么简单。。。。