js事件循环,宏任务,微任务

以下理解整合非原创,侵删

宏任务

宏任务包含:

script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

微任务包含:

Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)

运行机制(事件循环)

在单次循环中,一次最多处理一个macrotask(其他的仍然驻留在队列中),然而却可以处理完所有的microtask。

在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:

  • 执行一个宏任务(栈中没有就从事件队列中获取)
  • 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
  • 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  • 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
  • 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
    在这里插入图片描述

事件循环执行顺序

以下来自:https://www.cnblogs.com/shiyunfront/p/13095128.html

//主线程直接执行
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')
    })
})
//微事件1
process.nextTick(function() {
    console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    //微事件2
    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')
    })
})
首先浏览器执行js进入第一个宏任务进入主线程, 直接打印console.log('1')

• 遇到 setTimeout  分发到宏任务Event Queue中

• 遇到 process.nextTick 丢到微任务Event Queue中

• 遇到 Promise, new Promise 直接执行 输出 console.log('7');

• 执行then 被分发到微任务Event Queue中

•第一轮宏任务执行结束,开始执行微任务 打印 6,8

•第一轮微任务执行完毕,执行第二轮宏事件,执行setTimeout

•先执行主线程宏任务,在执行微任务,打印'2,4,3,5'

•在执行第二个setTimeout,同理打印 ‘9,11,10,12’

•整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。

Philip Roberts: What the heck is the event loop anyway? | JSConf EU 2014

在这里插入图片描述

练习(注释为自我理解)

  function testSometing() {
    console.log("执行testSometing");
    return "testSometing";
  }

  async function testAsync() {
    console.log("执行testAsync");
    return Promise.resolve("hello async");
  }

  async function test() {
    //1.
    console.log("test start...");
    const v1 = await testSometing();//关键点1
    //第一个被扔进第一轮事件循环的微任务队列
    //v1="testSometing"
    console.log(v1);
    const v2 = await testAsync();
    //v2="hello async"
    console.log(v2);
    console.log(v1, v2);
  }
  new Promise(((resolve, reject) => {
    console.log("test start...");

  }))

  test();

  var promise = new Promise((resolve)=> {
      console.log("promise start..");
      resolve("promise");
    });//关键点2
  //第二个被扔进第一轮事件循环的微任务队列
  promise.then((val)=> console.log(val));

  console.log("test end...")

//第一轮事件循环开始
//  同步任务
//    console.log("test start...");
//    console.log("执行testSometing");
//        console.log("promise start..");
//  console.log("test end...")
// 开始执行微任务队列
  // console.log(v1);  //    //v1="testSometing"
  //console.log(val)  val="promise"
//第二轮循环
//    console.log("执行testAsync");
//第三轮
//      console.log(v2);"hello async"
//   console.log(v1, v2);
async function async1() {
  console.log('2')
  await async2()
  console.log('7')
}

async function async2() {
  console.log('3')
}

setTimeout(function () {
  console.log('8')
}, 0)

console.log('1')
async1()
new Promise(function (resolve) {
  console.log('4')
  resolve()
}).then(function () {
  console.log('6')
})
console.log('5')
//第一轮事件循环
//同步
//12345
//微任务
//76
//第二轮
//8
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值