单线程和异步
-
js是单线程的(无论在浏览器还是nodejs)
-
浏览器中js执行和DOM渲染共用一个线程
-
异步,是单线程的解决方案
异步分为宏任务和微任务
-
宏任务,如setTimeout、setIterval、网络请求
-
微任务,如promise、async/await
-
微任务在下一轮DOM渲染之前执行,宏任务在之后执行
console.log('start')
setTimeout(() => {
console.log('timeout')
})
Promise.resolve().then(() => {
console.log('promise then')
})
console.log('end')
先执行同步任务,再执行微任务,再执行宏任务
const p = document.createElement('p')
p.innerHTML = 'new paragraph'
document.body.appendChild(p)
const list = document.getElementsByTagName('p')
console.log('length----', list.length)
console.log('start')
setTimeout(() => {
const list = document.getElementsByTagName('p')
console.log('timeout-length', list.length)
alert('timeout阻塞一下')
})
Promise.resolve().then(() => {
const list = document.getElementsByTagName('p')
console.log('promise-length', list.length)
alert('promise阻塞一下')
})
console.log('end')
Promise阻塞的时候,但是DOM没有渲染,说明微任务是在页面渲染之前触发
nodejs异步
-
nodejs同样使用es语法,也是单线程,也需要异步
-
异步任务也分宏任务和微任务
-
但是,它的宏任务和微任务,分不同类型,有不同优先级
console.info('start')
setImmediate(() => {
console.info('setImmediate')
})
setTimeout(() => {
console.info('setTimeout')
})
Promise.resolve().then(() => {
console.info('Promise')
})
process.nextTick(() => {
console.info('nextTick')
})
console.info('end')
nodejs宏任务优先级
-
Timers-setTimout、setInterval
-
I/O callbacks-处理网络、流、TCP的错误回调
-
Idle,prepare-闲置状态(nodejs内部使用)
-
Poll轮询-执行poll中的I/O队列
-
Check检查-储存setImmediate回调
-
Close callbacks-关闭回调,如socket.on('close')
nodejs微任务优先级
-
包括:promise,asycn/await,process.nextTick
-
process.nextTick优先级最高
nodejs event loop
-
执行同步代码
-
执行微任务(process.nextTick优先级最高)
-
按顺序执行6个类型的宏任务
每次执行宏任务之前先检查有没有微任务
浏览器和nodejs事件循环(event loop)的区别
-
浏览器和nodejs的event loop流程基本相同
-
nodejs宏任务和微任务分类型,有优先级