不想看文字,看视频推荐B站路径
基本执行机制
基本上是从第一行到最后一行按照顺序依次执行,由于执行速度问题,任务划分为同步和异步两种任务,但是异步任务中有部分任务存在连贯性,又划分为宏任务和微任务。
宏任务与微任务的理解
同步和异步的区别:同步是不需要等待的任务,异步是需要等待的任务
宏任务和微任务的区别:宏任务是不需要连贯的任务,微任务是需要连贯的任务
- 同步任务
- 异步任务(宏任务和微任务)
- 宏任务(macrotask):异步Ajax请求,setTimeout 、setInterval
- 微任务(microtask):Promise.then、Promise.catch和Promise.finally,process.nextTick
代码的执行顺序:先执行主线程执行栈中的代码(同步任务),那异步任务怎样执行的?
- 先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕(事件循环EventLoop)
相关试题
试题1
setTimeout(function() {
console.log('1');
})
new Promise(function(resolve) {
console.log('2');
}).then(function() {
console.log('3');
})
console.log('4');
//打印顺序 2 4 3 1
执行顺序1
- 遇到setTimeout,异步宏任务将其放到宏任务列表中 命名为time1
- new Promise 在实例化过程中所执行的代码都是同步执行的(function中的代码),输出2
- 将Promise中注册的回调函数放到微任务队列中,命名为then1
- 执行同步任务cosole…log(‘4’) ,输出4,至此执行栈中的代码执行完毕
- 从微任务队列取出任务then1到主线程中,输出3,至此微任务队列为空
- 从宏任务队列中取出任务time1到主线程中,输出1,至此宏任务队列为空
试题2
console.log(1)
setTimeout(function(){
console.log(2);
let promise = new Promise(function(resolve, reject) {
console.log(7);
resolve()
}).then(function(){
console.log(8)
});
},1000);
setTimeout(function(){
console.log(10);
let promise = new Promise(function(resolve, reject) {
console.log(11);
resolve()
}).then(function(){
console.log(12)
});
},0);
let promise = new Promise(function(resolve, reject) {
console.log(3);
resolve()
}).then(function(){
console.log(4)
}).then(function(){
console.log(9)
});
console.log(5)
//打印顺序 1 3 5 4 9 10 11 12 2 7 8
执行顺序2
- 执行同步任务console.log(1) ,输出1
- 遇到setTimeout放到宏任务队列中,命名time1
- 遇到setTimeout放到宏任务队列中,命名time2
- new Promise 在实例化过程中所执行的代码都是同步执行的(function中的代码),输出3
- 将Promise中注册的回调函数放到微任务队列中,命名为then1
- 将Promise中注册的回调函数放到微任务队列中,命名为then2
- 执行同步任务console.log(5),输出5
- 从微任务队列取出任务then1到主线程中,输出4
- 从微任务队列取出任务then2到主线程中,输出9,至此微任务队列为空
- 从宏任务队列中取出time2(注意这里不是time1的原因是time2的执行时间为0)
- 执行同步任务console.log(10),输出10
- new Promise 在实例化过程中所执行的代码都是同步执行的(function中的代码),输出11
- 将Promise中注册的回调函数放到微任务队列中,命名为then3,至此宏任务time2执行完成
- 从微任务队列取出任务then3到主线程中,输出12,至此微任务队列为空
- 从宏任务队列中取出time1,至此宏任务队列为空
- 执行同步任务console.log(2),输出2
- new Promise 在实例化过程中所执行的代码都是同步执行的(function中的代码),输出7
- 将Promise中注册的回调函数放到微任务队列中,命名为then4,至此宏任务time1执行完成
- 从微任务队列取出任务then3到主线程中,输出8,至此微任务队列为空
练手题3
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