JS事件循环机制、任务队列(细节updating...)

查阅资料、参考相关博客

第一篇:参考博客1
第二篇:参考博客2

下方JS打印顺序及解析

1.顺序

async function async1() {  
    console.log('2. async1 start')  
    await async2();  
    console.log('6. async1 end')  
}  
async function async2() {  
    console.log('3. async2')  
}  
console.log('1.script start')  
setTimeout(() => {  
    console.log('8. setTimeOut')  
},0)  
async1()  
new Promise((resolve) => {  
    console.log('4. promise1')  
    resolve();  
}).then(() => {  
    console.log('7. promise2')  
})  
console.log('5. script end')  

2.解析
考察知识点(事件循环、回调队列)
a. 字面简单解释下二者含义:
事件循环:JavaScript任务队列的顺序机制(事件循环),包含异步实现的两种任务机制Macrotasks(宏任务)、Microtasks(微任务)
回调队列 或 任务队列 - 暂时没想好怎么解释,也许在理解事件循环机制的过程中就很自然的懂了
macro-tasks包含:script(整体Js代码)、setTimeout、setInterval、setImmediate、I/O、UI Rendering
micro-tasks包含:proces.nextTick、Promise、object.observe(已废弃)、MutationObserve(html5新特性)
上述两项任务的分类按优先级进行排序

    i. 先选取macro-tasks中的第一项优先级任务,即script(整体Js代码)优先执行
    ii. 然后执行micro-tasks任务队列中的全部任务  
    iii. 再到macro-task任务队列中读取可执行下一项任务  
    iv. 然后执行全部micro-task任务队列  
    v. ...反复执行上述循环 直到两个队列的任务都执行完 

注:UI Rendering 在 micro-task任务之后执行,所以需要在UI渲染之前执行的逻辑,需要采用micro-task异步调用的方式进行调用,于此同时,micro-task任务不宜过多,当micro-task任务过多时,阻塞macro-task执行影响不大,但是严重时会阻塞UI渲染,故而导致页面不能更新。浏览器会基于性能方面考虑,对micro-task任务的个数进行限制。

鉴于上述问题依然不是很清晰,参考下一篇博客,继续进一步研读,略感清晰
第三篇:参考博客3

    function f1() {  
        console.log('2 我是f1');  
        for(var i = 0;i < 1000;i++) {  
            setTimeout(() => {  
                console.log('2-mic f1-setTimeout')  
            },500)  
        }  
    }  
    var a = new Promise((resolve,reject) => {  
        for(var i=0;i<1000;i++) {  
            console.log('1 promise')  
        }  
        resolve('over')  
    }).then((str) => {  
        console.log('1-mic',str)  
    })  
    function f2() {  
        console.log('3 f2')  
    }  
    f1()  
    f2()  

分析
step1:promise、f1对象实例化,f2放进主线程的堆内存中
step2:promise对象实例化后,其内部的同步代码块被放到主线程中进行执行,并且产生的异步任务(1-mic over)放入任务队列
step3:f1按顺序执行,先打印 ‘2 我是f1’,将产生的1000个定时器异步任务('2-mic f1-setTimeout')放入任务队列
step4:f2按顺序执行
step5:到这儿,主线程的执行栈内也就没有任务了,这时事件循环机制从任务队列中按顺序取出任务执行
step6:当主线程执行栈中没任务执行的时候去任务队列里取
step7:重复执行step6 直至任务队列空
注:第一个例子中的 async await搭配时 函数内的await异步直接执行,而不是放入任务队列等待下一批次调用,这一点需注意

至此,清晰了

Hold The Faith . Forever !

We can find a way .
Someday .
A path to a new world
And maybe
Maybe its just the begnning after all

你可能感兴趣的:(JS事件循环机制、任务队列(细节updating...))