new Promise((resolve, reject) => { // @1 console.log('执行Promise') resolve(11111) }).then(res => { // @2 console.log(res) // 11111 }) console.log('开始!') // @3 /* 结果执行顺序: 执行Promise 开始! 11111 由此可知 @1是同步 @2(也就是then里面)是异步 */
浏览器事件循环
- macro-task(宏任务):包括整体代码script,setTimeout,setInterval
- micro-task(微任务):Promise,process.nextTick
不同类型的任务会进入对应的Event Queue(循环队列),比如setTimeout和setInterval会进入相同的Event Queue。
事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。'
setTimeout(function() { console.log('setTimeout'); }) new Promise(function(resolve) { console.log('promise'); resolve('then') }).then(function(res) { console.log(res); }) console.log('console'); /* 1.这段代码作为宏任务,进入主线程。 2.先遇到setTimeout,那么将其回调函数注册后分发到宏任务Event Queue。(注册过 程与上同,下文不再描述) 3.接下来遇到了Promise,new Promise立即执行,then函数分发到微任务Event Queue。 4.遇到console.log(),立即执行。 5.到这,整体代码script作为第一个宏任务执行结束,看看有哪些微任务?我们发现了 then在微任务Event Queue里面,执行。 6.ok,第一轮事件循环结束了,我们开始第二轮循环,当然要从宏任务Event Queue开 始。我们发现了宏任务Event Queue中setTimeout对应的回调函数,立即执行。 7.结束。 打印顺序: promise console then setTimeout */