0


宏任务和微任务

    JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。

    为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为,防止主线程的不阻塞,Event Loop 的方案应用而生。Event Loop 包含两类:一类是基于 Browsing Context,一种是基于 Worker。

    二者的运行是独立的,也就是说,每一个 JavaScript 运行的"线程环境"都有一个独立的 Event Loop,每一个 Web Worker 也有一个独立的 Event Loop。

一、宏任务和微任务

先做题:

setTimeout(function(){
            console.log('setTimeout') 
        },0)         
        //同步
        console.log('script start')    
        async function async1(){
            //同步
            console.log('async1 start');
            await async2()
            //异步
            console.log('async1 end')
        }    
        async function async2(){
            //同步
            console.log('async2 end')
        }    
        //微任务
        new Promise(function(resolve){
            //同步
            console.log('promise')
            for (var i = 0; i <10000; i++) {
                if (i === 10) {
                    console.log("3")
                }
                i == 9999 && resolve('4')
            }
            resolve();
        }).then(function(val){
            console.log(val)
            //异步
            console.log('promise1')
        }).then(function(res){
            console.log(res)
            console.log('promise2')
        })    
        //微任务
        async1();     
        //同步
        console.log('script end')

宏任务:

    setTimeout setInterval Ajax DOM事件  script(整体代码)   I/OUI交互事件   postMessageMessage  Channel setImmediate(Node.js 环境)

微任务:

    Promise async/await  Object.observe MutationObserver    process.nextTick(Node.js 环境)

微任务比宏任务的执行时间要早

    异步和单线程

    异步和单线程是相辅相成的,js是一门单线程脚本语言,所以需要异步来辅助

异步和同步的区别:

    异步不会阻塞程序的执行,

    同步会阻塞程序的执行,

前端使用异步的场景:

定时任务:

    setTimeout,setInverval

网络请求:

    ajax请求,动态<img>加载

    事件绑定

任务队列和event loop(事件循环)

    1)所有的同步任务都在主线程上执行,行成一个执行栈。

    2)除了主线程之外,还存在一个任务列队,只要异步任务有了运行结果,就在任务列队中植入一个时间标记。

    3)主线程完成所有任务(执行栈清空),就会读取任务列队,先执行微任务队列在执行宏任务队列。

    4)重复上面三步。

    只要主线程空了,就会读取任务列队,这就是js的运行机制,也被称为 event loop(事件循环)。

考察的是事件循环和回调队列。注意以下几点:

    Promise 优先于 setTimeout 宏任务,所以 setTimeout 回调会最后执行

    Promise 一旦被定义就会立即执行

    Promise 的 resolve 和 reject  是异步执行的回调。所以 resolve() 会被放到回调队列中,在主函数执行完和 setTimeout 之前调用

    await 执行完后,会让出线程。async 标记的函数会返回一个 Promise 对象

解析:

    首先,事件循环从宏任务(macrostack)队列开始,这个时候,宏任务队列中,只有一个 script (整体代码)任务。从宏任务队列中取出一个任务来执行。

    首先执行 console.log('script start'),输出 ‘script start'

    遇到 setTimeout 把 console.log('setTimeout') 放到 macrotask 队列中

    执行 aync1() 输出 ‘async1 start' 和 'async2' ,把 console.log('async1 end') 放到 micro 队列中

    执行到 promise ,输出 'promise1' ,把 console.log('promise2') 放到  micro 队列中

    执行 console.log('script end'),输出 ‘script end'

    macrotask 执行完成会执行 microtask ,把 microtask quene 里面的 microtask 全部拿出来一次性执行完,所以会输出 'async1 end' 和 ‘promise2'

    开始新一轮的事件循环,去除执行一个 macrotask 执行,所以会输出 ‘setTimeout'
标签: javascript java vscode

本文转载自: https://blog.csdn.net/m0_65558076/article/details/124210958
版权归原作者 Anastasia.. 所有, 如有侵权,请联系我们删除。

“宏任务和微任务”的评论:

还没有评论