首先,我们必须弄清楚EventLoop的微任务、宏任务流程:
。。。
然后,我们要知道哪些是宏任务,哪些是微任务:
宏任务:
- <script>标签包含的主代码块
- setTimeout
- setInterval
- setImmediate ()---Node
- MessageChannel
微任务:
- process.nextTick ()---Node
- Promise.prototype.then()
- Promise.prototype.catch()
- Promise.prototype.finally()
- Object.observe()---已废弃
- MutationObserver---浏览器
既不是宏认为,也不是微任务,与渲染有关
- requestAnimationFrame ()---浏览器
- requestIdleCallback()---浏览器
列举一些例子,看看是否掌握了执行顺序:
console.log('script start')
复制代码
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
// script start => async2 end => Promise => script end => async1 end =>
//promise1 => promise2 => setTimeout
复制代码
2.
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
return Promise.resolve().then(()=>{
console.log('async2 end1')
})
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
// script start => async2 end => Promise => script end =>async2 end1 =>
//promise1 => promise2 => async1 end => setTimeout
复制代码
3.
setTimeout(function () {
console.log('9')
}, 0)
console.log('1')
async function async1() {
console.log('2')
await async2()
console.log('8')
}
async function async2() {
return new Promise(function (resolve) {//如果不加return结果会怎么样呢?
console.log('3')
resolve()
}).then(function () {
console.log('6')
})
}
async1()
new Promise(function (resolve) {
console.log('4')
resolve()
}).then(function () {
console.log('7')
})
console.log('5')
复制代码
4.
function test() {
console.log(1)
setTimeout(function () { // timer1
console.log(2)
}, 1000)
}
test();
setTimeout(function () { // timer2
console.log(3)
})
new Promise(function (resolve) {
console.log(4)
setTimeout(function () { // timer3
console.log(5)
}, 100)
resolve()
}).then(function () {
setTimeout(function () { // timer4
console.log(6)
}, 0)
console.log(7)
})
console.log(8)
复制代码
5.
async function async1() {
console.log('2')
const data = await async2()
console.log(data)
console.log('8')
}
async function async2() {
return new Promise(function (resolve) {
console.log('3')
resolve('await的结果')
}).then(function (data) {
console.log('6')
return data
})
}
console.log('1')
setTimeout(function () {
console.log('9')
}, 0)
async1()
new Promise(function (resolve) {
console.log('4')
resolve()
}).then(function () {
console.log('7')
})
console.log('5')
复制代码
6.
setTimeout(function () {
console.log('8')
}, 0)
async function async1() {
console.log('1')
const data = await async2()
console.log('6')
return data
}
async function async2() {
return new Promise(resolve => {
console.log('2')
resolve('async2的结果')
}).then(data => {
console.log('4')
return data
})
}
async1().then(data => {
console.log('7')
console.log(data)
})
new Promise(function (resolve) {
console.log('3')
resolve()
}).then(function () {
console.log('5')
})
复制代码
7.
let p = new Promise(resolve => {
resolve(1);
Promise.resolve().then(() => console.log(2));
console.log(4);
}).then(t => console.log(t));
console.log(3);
复制代码
8.下面的两道题来自 Eventloop 不可怕,可怕的是遇上 Promise。
const p1 = new Promise((resolve, reject) => {
console.log('promise1');
resolve();
})
.then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve();
})
.then(() => {
console.log('then21');
})
.then(() => {
console.log('then23');
});
})
.then(() => {
console.log('then12');
});
const p2 = new Promise((resolve, reject) => {
console.log('promise3');
resolve();
}).then(() => {
console.log('then31');
});
const p1 = new Promise((resolve, reject) => {
console.log('promise1'); // 1
resolve();
})
.then(() => {
console.log('then11'); // 2
return new Promise((resolve, reject) => {
console.log('promise2'); // 3
resolve();
})
.then(() => {
console.log('then21'); // 4
})
.then(() => {
console.log('then23'); // 5
});
})
.then(() => {
console.log('then12'); //6
});
复制代码
9.执行下面这段代码,执行后,在 5s 内点击两下,过一段时间(>5s)后,再点击两下,整个过程的输出结果是什么?
setTimeout(function(){
for(var i = 0; i < 100000000; i++){}
console.log('timer a');
}, 0)
for(var j = 0; j < 5; j++){
console.log(j);
}
setTimeout(function(){
console.log('timer b');
}, 0)
function waitFiveSeconds(){
var now = (new Date()).getTime();
while(((new Date()).getTime() - now) < 5000){}
console.log('finished waiting');
}
document.addEventListener('click', function(){
console.log('click');
})
console.log('click begin');
waitFiveSeconds();
复制代码
10.
setTimeout(() => {
console.log(2)
}, 2)
setTimeout(() => {
console.log(1)
}, 1)
setTimeout(() => {
console.log(0)
}, 0)
复制代码
11.
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
// 输出:5 5 5 5 5
复制代码
12.
setTimeout(function () {
console.log(1);
}, 0);
Promise.resolve(function () {
console.log(2);
})
new Promise(function (resolve) {
console.log(3);
});
console.log(4);
//上述代码的输出结果是什么???
复制代码
13.
new Promise((resolve,reject)=>{
console.log("promise1")
resolve()
}).then(()=>{
console.log("then11")
return new Promise((resolve,reject)=>{
console.log("promise2")
resolve()
}).then(()=>{
console.log("then21")
}).then(()=>{
console.log("then23")
})
}).then(()=>{
console.log("then12")
})
复制代码
14.
new Promise((resolve,reject)=>{
console.log("promise1")
resolve()
}).then(()=>{
console.log("then11")
new Promise((resolve,reject)=>{
console.log("promise2")
resolve()
}).then(()=>{
console.log("then21")
}).then(()=>{
console.log("then23")
})
}).then(()=>{
console.log("then12")
})
new Promise((resolve,reject)=>{
console.log("promise3")
resolve()
}).then(()=>{
console.log("then31")
})
复制代码
15.
console.log('1');
new Promise((resolve, reject) => {
console.log('2');
resolve();
}).then(() => {
console.log('5');
}).then(() => {
console.log('7');
return new Promise(resolve => {resolve(); })
}).then(() => {
console.log('9-----p1wai');
})
new Promise((resolve, reject) => {
console.log('3');
resolve();
}).then(() => {
console.log('6');
}).then(() => {
console.log('8');
}).then(() => {
console.log('10');
}).then(() => {
console.log('11');
}).then(() => {
console.log('12--p2wai');
}).then(() => {
console.log('13--p2wai');
}).then(() => {
console.log('14');
})
console.log('4');
复制代码
参考:
浏览器与Node的事件循环(Event Loop)有何区别?
总结:JavaScript异步、事件循环与消息队列、微任务与宏任务
8张图让你一步步看清 async/await 和 promise 的执行顺序
从event loop到async await来了解事件循环机制