事件轮询

javascript 中,任务分为两种:

  1. 宏任务:包括整体代码script,setTimeout,setInterval, I/O,UI Rendering
  2. 微任务:Promise.then(非new Promise),process.nextTick(node中)

事件执行顺序:

先执行宏任务,再执行微任务。任务又分,同步任务,异步任务。同步任务进入主线程,异步任务进入Event Table并注册函数,异步事件完成后,会将回调函数放入Event Quene中(宏任务和微任务是不用的Event Quene)。同步任务完成后,会从Event Quene中读取事件放入主线程执行,回调函数中可能还函数有不同的任务,会循环执行上述操作的。

例子1:

// a
console.log('script start');

// b
setTimeout(function() {// e
        console.log('setTimeout');
}, 0);

// c
Promise.resolve().then(function() { // f 
  console.log('promise1');
}).then(function() {// g
  console.log('promise2');
});

//d
console.log('script end');

// script start
// script end
// promisel1
// promisel2
// setTimeOut

第一次轮询,刚开始微任务为空

执行宏任务:执行a,b,将e添加到Event Table,执行c,将f,g添加到微任务,执行d,

打印结果:a,d的值(script start, script end)

执行微任务:里面有f,g,执行f,g

打印结果:f,g的值(promise1, promise2)

第二次轮询:

执行宏任务:执行e

打印结果:e (setTimeout)

执行微任务:空

例子2:

setTimeout(function() {// a
    console.log('setTimeout');
},1000)

new Promise(function(resolve) {// b
    console.log('promise');
    resolve();
}).then(function() {// c
    console.log('then');
})
// d
console.log('console');

// promise
// console
// then
// setTimeout

第一次轮询:

执行宏任务:将a放到Event Table注册,执行同步b,添加c到微任务,执行d

打印结果:b,d的值(promise, console)

执行微任务:执行c

打印结果:c(then)

第二次轮询:

执行宏任务:a已经执行完毕,提取到主线程

打印结果:a(setTimeout)

执行微任务:空

例子3:

// a
console.log('script start')

async function async1() { // b
  // c
  await async2()
  // d
  console.log('async1 end')
}
async function async2() {// e
  console.log('async2 end') 
}
async1()

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

new Promise(resolve => {// g
  console.log('Promise')
  resolve()
})
  .then(function() {// h
    console.log('promise1')
  })
  .then(function() {// i
    console.log('promise2')
  })

// j
console.log('script end')

// script start
// async2 end
// Promise
// script end
// promise1
// promise2
// async1 end
// setTimeout

// 作者:光光同学
// 链接:https://juejin.im/post/5c3d8956e51d4511dc72c200
// 来源:掘金
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

async/await 在底层转换成了 promise 和 then 回调函数。
也就是说,这是 promise 的语法糖。
每次我们使用 await, 解释器都创建一个 promise 对象,然后把剩下的 async 函数中的操作放到 then 回调函数中。每个 await,会新产生一个promise,但这个过程本身是异步的,所以该await后面不会立即调用。

第一次轮询:

执行宏任务:执行a,b,c,e,将f放到Event Table,执行g,将h,i放入微任务,执行j

打印结果:a,e,g,j(script start,async2 end,Promise,script end)

执行微任务:执行h,i,然后回到await位置返回的Promise的resolve函数,将其对待微任务队列中,执行

打印结果:h,i,d(promise1,promise2,async1 end)

第二次轮询

执行宏任务:执行f

打印结果:f(setTimeout)

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容