js中异步要发生的一些事

发布于:2022-08-05 ⋅ 阅读:(348) ⋅ 点赞:(0)


前言

网页有各种讲js的单线程,和同步异步的.说真的,看半天我挺晕的,感觉本来没有多大的事,硬是被说的好复杂.


一、js为什么是单线程?

  • 严谨的描述为: 浏览器中的js执行和UI渲染是在一个线程中顺序发生的。

  • js引擎在解析HTML生成DOM树的过程中,如果遇到js,主线程则会停止DOM的渲染,先去执行js,js解析完成,才会继续解析HTML.

  • 为什么遇到js主线程,会停止执行html,等js执行完毕,才会继续执行html呢?

  • 主线程在解析html,生成DOM树的过程中,会执行style,layout,render等操作,而js可以操作DOM,cssDOM,会影响主线程在解析HTML的最终渲染效果,最终的页面渲染和会变得不可控.

  • 考虑到最终页面的渲染效果的一致性,所以js在浏览器中的实现,被设计成为了JS执行阻塞UI渲染型。

二、js代码执行过程

1.执行发生的事

  • js代码按照从上到下的物理顺序执行的时候,会形成执行栈,队列,和堆三部分东西.

  • 堆(heap,存放对象,数据,垃圾回收就是这里)和栈(stack,存放基本数据类型),队列(queue 存放等待执行的任务)

  • 栈分为执行栈和内存栈两种,内存栈只存变量,执行栈负责代码执行。执行栈,先进后出,直到栈被清空。它们之间就是卧室和厨房的关系。

在这里插入图片描述

2.一段代码到底怎么运行

1, js是单线程的,一次只能执行一个任务(任务即代码表达式),代码被执行必须放入执行栈.

2, 代码被分为同步任务和异步任务,同步任务会立即加入执行栈.

3, 异步任务,在物理顺序执行到它时,会被js引擎直接跳过.当异步任务有了结果就会放在队列上(task queque)(遵从先进先出).

4,等待执行栈为空时,通过event Loop 获取获取队列的第一个任务,放入执行栈.

5, js中分为执行栈和消息队列,当执行栈为空,则去消息队列中获取.消息队列分为,微任务队列和宏任务队列.

在这里插入图片描述Js 中,有两类任务队列:宏任务队列(macro tasks)和微任务队列(micro tasks)。宏任务队列可以有多个,微任务队列只有一个。

  • 宏任务:script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering.
  • 微任务:process.nextTick, Promise, Object.observer, MutationObserver.

看下面代码的执行流程:

    console.log(1, 'log')
    new Promise(function (resolve) {
      console.log(3)
      resolve(100)
    }).then(function (data) {
      console.log(data, 'promise')
    })
    setTimeout(function () {
      console.log(4, 'setTimeout');
    })
    console.log(2, 'log')

在这里插入图片描述在这里插入图片描述微任务和宏任务之间的选择
在这里插入图片描述

3 补充几个概念

队列

  • 队列的特点就是先进先出(First In First Out ).
  • 先开始的任务执行完后,才能开始执行后续任务.
  • 所以的异步任务完成后都会加入队列中, 一旦当前执行栈空了,轮询就会取出消息队列的第一条,传入程序。程序开始执行对应的回调函数,等到执行完,再处理下一条消息。

事件轮询

  • 所谓Event Loop机制,指的是一种内部循环,用来一轮又一轮地处理消息队列之中的消息,即执行对应的回调函数。

线程

  • 主线程只会做一件事情,就是从消息队列里面取消息、执行消息,再取消息、再执行。
  • 当消息队列为空时,就会等待直到消息队列变成非空。而且主线程只有在将当前的消息执行完成后,才会去取下一个消息。这种机制就叫做事件循环机制,取一个消息并执行的过程叫做一次循环

总结

1 JS内存分为堆内存和栈内存
2 引用类型在栈中保存指针,在堆中保存对象值
3 所有JS代码运行,都需要放入执行栈中.执行代码前,会先创建执行上下文执行,上下文包含了三种(全局、函数、eval.
4 同步任务先执行,异步任务放队列.
5 微任务先执行,宏任务后执行.
6 微任务全部拉入执行栈,宏任务一次拉一个.
7 栈是先进后出,队列是先进先出.

本文含有隐藏内容,请 开通VIP 后查看