javascript
中,任务分为两种:
- 宏任务:包括整体代码script,setTimeout,setInterval, I/O,UI Rendering
- 微任务: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)