什么是事件循环?Event Loop 宏任务/微任务

从Event Loop 到 async await
https://www.jianshu.com/p/8dccfa90ba59
运行在宿主环境中的Javascript引擎针对单线程,提供了一种机制来更高效地处理多个任务,这个机制不断地重复处理任务称为事件循环,事件循环具体地执行过程分为以下4步:
1.先执行主线程中的任务
2.当主线程空闲时,再从任务队列中读取任务,继续执行。
3.即使主线程阻塞了,任务队列还是会继续接收任务。
4.主线程不断地重复第2步操作。
http://www.ruanyifeng.com/blog/2013/10/event_loop.html
什么是 Event Loop?
https://github.com/forthealllight/blog/issues/5
https://cloud.tencent.com/developer/article/1476737
从promise、process.nextTick、setTimeout出发,谈谈Event Loop中的Job queue

setTimeout(function(){console.log(1)},0);
new Promise(function(resolve,reject){
	// promise 构造部分是同步执行的
console.log(2);
resolve();
}).then(function(){console.log(3)
}).then(function(){console.log(4)});
process.nextTick(function(){console.log(5)}); //nodejs里的定时器,执行顺序高于promise,promise高于setTimeout
console.log(6); 
// 2,6,5,3,4,1

首先分析Job queue的执行顺序:

script(主程序代码)——>process.nextTick——>promise——>setTimeout

I) 主体部分: 定义promise的构造部分是同步的,
因此先输出2 ,主体部分再输出6(同步情况下,就是严格按照定义的先后顺序)

II)process.nextTick: 输出5

III)promise: 这里的promise部分,严格的说其实是promise.then部分,输出的是3,4

IV) setTimeout : 最后输出1

综合的执行顺序就是: 2——>6——>5——>3——>4——>1

Event Loop
任务队列中,在每一次事件循环中,macrotask(宏任务)只会提取一个执行,而microtask(微任务)会一直提取,直到microsoft队列为空为止。
也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止。
//意思是主线程执行完成后,开始执行任务队列里的任务,直到队列任务全被执行然后结束
而事件循环每次只会入栈一个macrotask,主线程执行完成该任务(主线程中的同步任务的代码块)后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。
//在执行任务队列中的任务时,每次Event Loop只会入栈一个宏任务(主线程中的同步任务),执行完宏任务后检查队列中的微任务,执行完所有的微任务再来执行剩余的宏任务(定时器等等)
在这里插入图片描述

常见的宏任务和微任务:
macrotasks:js主代码块, setTimeout, setInterval, setImmediate, MessageChannel, I/O, UI rendering(UI渲染)
宏任务–优先级:主代码块 > setImmediate > MessageChannel > setTimeout / setInterval
microtasks: process.nextTick, Promise, MutationObserver
微任务–优先级:process.nextTick > Promise > MutationObserver
  [宏任务:macro task]
- 定时器
- 事件绑定
- ajax
- 回调函数
- Node中fs可以进行异步的I/O操作

[微任务:micro task]
- Promise(async/await) => Promise并不是完全的同步,当在Excutor中执行resolve或者reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会再去调用resolve/reject把存放的方法执行
- process.nextTick (node中实现的api,把当前任务放到主栈最后执行,当主栈执行完,先执行nextTick,再到等待队列中找)
   - MutationObserver (创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。)
https://zhuanlan.zhihu.com/p/257069622

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})
//1,7,6,8,2,4,3,5,9,11,10,12




setTimeout(first(),0); //或者setTimeout(first());
new Promise(function(resolve){
  console.log('2');
  resolve();
}).then(function(){
  console.log('3')
});
console.log('4');
function first(){
  console.log('1')
}
//1243 因为在setTimeout里面,调用的是first(),带了(),而不是first
async function async1() {
  console.log('A');
  await async2()
  console.log('B');
}
async function async2() {
  console.log('C');
}
console.log('D');
setTimeout(function() { 
  console.log('E');
})
async1()
new Promise(function(resolve) { 
  console.log('F');
  resolve()
}).then(function() {
  console.log('G');
})
console.log('H');
// D A C F H G B E
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值