查阅资料、参考相关博客
下方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