四、JavaScript任务管理[同步与异步、宏任务、微任务]

一、同步与异步

解释:js是一个单线程的语言,但是为了发送ajax渲染等需要需要异步请求,为了防止主线程的阻塞,(事件循环)Event Loop 的方案应用而生。

同步:普通的代码如console.log()这种就是同步代码,其会在主进程中执行,如果同步代码执行时间长会阻止进程

异步:对于如ajaxsetTimeout,这种就是异步请求,其不会阻塞主进程,当程序运行到异步代码时,并不是立刻执行它,而是把它添加到一个宏任务当中去,其中宏任务执行完会先看看它下面有没有微任务,如果有就会把微任务也执行完,再执行下一个宏任务(下面会介绍),之后会直接执行它后面的同步代码,而它本身会在当前同步代码执行完毕后才会执行(重点)

二、宏任务

解释:其内容有<script>整体代码setTimeoutsetIntervalsetImmediateAjaxDOM事件,这些都是宏事件,主进程在遇到这些内容时,会把其添加到宏任务中,而宏任务会在同步代码执行完毕后才会执行(注意按自己的认识理解,这里说的不标准)。

注意:执行第一个宏任务的同时,第二个个宏任务同时会执行(他们都是异步不会阻塞)

分析:下面出现了两个宏任务,一个是<script>整体代码(注意体会理解这个),另一个是setTimeout,其中<script>整体代码setTimeout都没有微任务,也就是说执行完同步代码后,直接执行宏任务,故先执行同步代码console.log(123),再执行微任务 setTimeout(()=>{ console.log(321) },0)

    <script>
        setTimeout(()=>{
            console.log(321)
        },0)
        console.log(123)
    </script>
// 最终结果 
123
321

三、微任务

解释:Promise.then (需要在前面获取resolve之后的then才能挂载到当前宏任务后面)是典型的微任务,目前最多用的也就是它

注意:例如then只有收到resolve时才会执行,没有时它会等待

分析:下面出现了两个宏任务,一个是<script>整体代码(注意体会理解这个),另一个是setTimeout,先执行同步代码console.log(1)和(包括Promise里面的第一个如果是同步代码也会被立即执行)console.log(4),之后执行<script>整体代码里面的微任务.then(() => { console.log(5) }),再执行下一个宏任务 setTimeout(() => { console.log(2) }, 0)


    <script>
        setTimeout(() => {
            console.log(2)
        }, 0)
        console.log(1)
        new Promise((resolve) => {
            console.log(4)
            resolve('success')

        }).then(() => {
            console.log(5)
        })
    </script>
 // 最终结果
1
4
5
2

四、图示总结

解释:可以自己先看看能否想出输出的结果,不明白可以看下面的图解
代码:

		// 标志A
        setTimeout(()=>{
            console.log(2)
            // 标志D
            setTimeout(()=>{
                console.log(3)
            },0)
            // 标志F
            Promise.resolve('ok').then(()=>{
                console.log(4)
            }).then(()=>{
                console.log(5)
            })
        },0)
        // 标志B
        setTimeout(()=>{
            console.log(6)
            // 标志G
            Promise.resolve('ok').then(()=>{
                console.log(7)
            }).then(()=>{
                console.log(8)
            })
        },0)
        // 标志C
        Promise.resolve('ok').then(()=>{
                console.log(9)
            }).then(()=>{
                console.log(10)
            })
        console.log(1)
 // 结果
1
9
10
2
4
5
6
7
8
3

解释:

  1. 代码运行到标志A,将标志A添加到宏队列
    在这里插入图片描述

  2. 代码开始运行标志B(此时标志A中代码(包括标志D和标志F),都已经同标志B一样添加到宏任务中),将标志B添加到宏队列中

    在这里插入图片描述

  3. 此时开始执行同步代码,然后开始运行标志C,它是当前宏任务<script>整体代码的微任务(其运行的同时,其它宏任务也会按顺序依次开始,不会阻塞,但如果微任务中有同步代码,照样会先执行同步代码影响后面的进行
    在这里插入图片描述

  4. 此时主进程代码都已经执行,开始执行宏队列中代码(其运行的同时,其它宏任务也会按顺序依次开始,不会阻塞,但如果微任务中有同步代码,照样会先执行同步代码影响后面的进行

在这里插入图片描述
5. 执行标志A中代码(顺序先执行同步代码宏任务加入到宏队列,微任务等待同步代码执行完后再执行),此时,执行完打印,在这其中向宏队列添加了宏任务:标志D。(其运行的同时,其它宏任务也会按顺序依次开始,不会阻塞,但如果微任务中有同步代码,照样会先执行同步代码影响后面的进行
在这里插入图片描述

6.执行宏任务标志B,先执行打印(同步代码),再执行当前宏代码下的微任务(其运行的同时,其它宏任务也会按顺序依次开始,不会阻塞,但如果微任务中有同步代码,照样会先执行同步代码影响后面的进行
在这里插入图片描述
6. 最后执行宏任务:标志D
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值