同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。当指定的事情完成时,Event Table会将这个函数移入Event Queue。主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。上述过程会不断重复,也就是常说的Event Loop(事件循环)。
————————————————
————————————————
首先在 宏任务 的队列中取出第一个任务,执行完毕后取出 微任务 队列中的所有任务顺序执行;之后再取出一个宏任务
————————————————
而宏任务一般是:包括整体代码script,setTimeout,setInterval,setImmediate。
微任务:romise.then(非new Promise),process.nextTick(node中),MutationObserver
setTimeout(function () {
console.log('1')
});
new Promise(function (resolve) {
console.log('2');
resolve();
}).then(function () {
console.log('3')
});
console.log('4');
2....4.....3.....1
setTimeout(function () {
console.log('a');
new Promise(function (resolve,reject) {
resolve();
console.log('b');
}).then(function () {
console.log('c')
})
},1000)
setTimeout(function () {
console.log('d');
},0)
new Promise(function (resolve,reject) {
reject();
console.log('e');
}).then(function () {
console.log('f')
}).catch(()=>{
console.log('g')
})
console.log('h')
e....h.....g...d.....a.....b.....c...
async function async1() {
console.log('1')
await async2()
console.log('2')
}
async function async2() {
console.log('3')
}
console.log('4')
setTimeout(function () {
console.log('5')
}, 0)
async1();
new Promise(function (resolve) {
console.log('6')
resolve();
}).then(function () {
console.log('7')
})
console.log('8')
41368275
再次了解事件循环:
1、为什么js是单线程
这与浏览器的用途有关,JS的主要用途是与用户互动和操作DOM。设想一段JS代码,分发到两个并行互不相关的线程上运行,一个线程在DOM上添加内容,另一个线程在删除DOM,那么会发生什么?以哪个为准?所以为了避免复杂性,JS从一开始就是单线程的,以后也不会变。
2、为什么js是单线程但没有阻塞代码的运行
既然JS是单线程的,那么诸如onclick回调,setTimeout,Ajax这些都是怎么实现的呢?是因为浏览器或node(宿主环境)是多线程的,即浏览器搞了几个其他线程去辅助JS线程的运行。
浏览器有很多线程,例如:
1、GUI 渲染线程
2、JS 引擎线程
3、定时器触发线程 (setTimeout)
4、浏览器事件线程 (onclick)
5、http 异步线程
6、EventLoop轮询处理线程
7、...
其中,1、2、4为常驻线程,1,2线程互斥;