宏任务
script/UI渲染/setTimeout/setInterval/setImmediate
messageChnanel/requestAnimationFram/用户交互/ajax
微任务
promise.then /mutationObserver/process.nextTick
setImmediate
在poll阶段完成之后执行
setImmediate与setTimeout执行顺序受进程性能影响
在一个读取文件执行的回调函数内setImmediate先于setTimeout执行
messageChannel
const channel = new MessageChannel();
const { port1, port2 } = channel;
console.log(port1, port2);
requestAnimationFrame
requestAnimationFrame vs setInterval
1.布局控制的逻辑不同
setInterval 回调有多少DOM操作,进行多少计算 绘制
requestAnimationFrame 把所有DOM操作集中起来 一次性进行统一的计算并进行统一的绘制
2.窗口最小化时 运行情况不同
setInterval 一直执行回调函数
requestAnimationFrame 在最小化窗口时 暂停程序 页面打开时 从暂停的时候 重新开始
3. setInterval 会导致无意义的回调执行 -> 重绘重排(及时时间间隔小于刷新率)
requestAnimationFrame 不会
nextTick
作为微任务是优先于promise执行的
事件循环练习题
document.body.style.backgroundColor = 'orange';
console.log(1);
setTimeout(() => {
document.body.style.backgroundColor = 'green';
console.log(2);
}, 100);
Promise.resolve(3).then((num) => {
document.body.style.backgroundColor = 'purple';
console.log(num);
});
console.log(4);
bgColor: orange -> 每渲染
1
4
bgColor: purple -> 渲染
3
bgColor: green -> 没渲染
2
bgColor: green -> 渲染
Promise.resolve().then(() => {
console.log('p1');
setTimeout(() => {
console.log('s2');
}, 0);
});
setTimeout(() => {
console.log('s1');
Promise.resolve().then(() => {
console.log('p2');
});
});
Promise(executor) 执行器同步代码
console.log(1);
setTimeout(() => {
console.log(2);
}, 10);
new Promise(function (resolve, reject) {
console.log(3);
resolve('');
console.log(4);
}).then((res) => {
console.log(5);
});
console.log(6);
当去掉resolve(‘’) 就不会打印5
console.log(1);
setTimeout(() => {
console.log(2);
}, 10);
new Promise(function (resolve, reject) {
console.log(3);
console.log(4);
}).then((res) => {
console.log(5);
});
console.log(6);
console.log(1);
setTimeout(() => {
console.log(2);
}, 10);
new Promise(function (resolve, reject) {
console.log(3);
reject('');
console.log(4);
}).then((res) => {
console.log(5);
});
console.log(6);
console.log(1);
setTimeout(() => {
Promise.resolve().then(() => {
console.log('p2', 2);
});
console.log(2);
}, 10);
new Promise(function (resolve, reject) {
console.log(3);
resolve('');
console.log(4);
}).then((res) => {
setTimeout(() => {
console.log('p1', 5);
}, 0);
});
console.log(6);
console.log(1);
setTimeout(() => {
Promise.resolve().then(() => {
console.log('p2', 2);
});
console.log(2);
}, 10);
new Promise(function (resolve, reject) {
console.log(3);
resolve('');
console.log(4);
}).then((res) => {
setTimeout(() => {
console.log('p1', 5);
}, 20);
});
console.log(6);
let res = function () {
console.log(1);
return new Promise((resolve, reject) => {
console.log(2);
resolve(4);
});
};
new Promise(async (resolve, reject) => {
console.log(3);
let test = await res();
/*
await res()
new Promise((resolve,reject)=>{
console.log(2)
resolve(4)
}).then((res)=>{})
res().then((res)=>{
console.log(test)
})
*/
console.log(test);
});
console.log(5);
new Promise((resolve, reject) => {
console.log(6);
});
console.log(7);
let res = function () {
console.log(1);
return new Promise((resolve, reject) => {
setTimeout(() => {
new Promise((resolve) => {
console.log(2);
setTimeout(() => {
console.log(3);
});
});
}, 0);
resolve(5);
});
};
new Promise(async (resolve, reject) => {
setTimeout(() => {
Promise.resolve().then(() => {
console.log(4);
});
}, 0);
let test = await res();
console.log(test);
});
setTimeout(() => {
console.log(6);
}, 0);
new Promise((resolve, reject) => {
setTimeout(() => {
console.log(7);
}, 0);
});
console.log(8);
事件处理函数的回调是宏任务
每执行完一个红任务 清空此时的微任务队列
var oBtn = document.getElementById('btn');
oBtn.addEventListener(
'click',
() => {
console.log('1');
Promise.resolve('m1').then((str) => {
console.log(str);
});
},
false
);
oBtn.addEventListener('click', () => {
console.log('2');
Promise.resolve('m2').then((str) => {
console.log(str);
});
});
oBtn.click();
但是点击调用时
var oBtn = document.getElementById('btn');
oBtn.addEventListener(
'click',
() => {
setTimeout(() => {
console.log('1');
});
Promise.resolve('m1').then((str) => {
console.log(str);
});
},
false
);
oBtn.addEventListener('click', () => {
setTimeout(() => {
console.log('2');
});
Promise.resolve('m2').then((str) => {
console.log(str);
});
});
oBtn.click();
console.log('start');
const interval = setInterval(() => {
console.log('setInterval');
}, 0);
setTimeout(() => {
console.log('setTimeout 1');
Promise.resolve()
.then(() => {
console.log('promise 3');
})
.then(() => {
console.log('promise 4');
})
.then(() => {
setTimeout(() => {
console.log('setTimeout 2');
Promise.resolve()
.then(() => {
console.log('promise 5');
})
.then(() => {
console.log('promise 6');
})
.then(() => {
clearInterval(interval);
});
}, 0);
});
}, 0);
Promise.resolve()
.then(() => {
console.log('promise 1');
})
.then(() => {
console.log('promise 2');
});
start
promise 1
promise 2
setInterval
setTimeout 1
promise 3
promise 4
setInterval
setTimeout 2
promise 5
promise 6
setTimeout(() => {
console.log('setTimeout 1');
setTimeout(() => {
console.log('setTimeout 3');
}, 1000);
Promise.resolve().then((data) => {
console.log('then3');
});
}, 1000);
Promise.resolve().then((data) => {
console.log('then1');
console.log('then4');
Promise.resolve().then((data1) => {
console.log('then6');
});
});
Promise.resolve().then((data) => {
console.log('then2');
console.log('then5');
setTimeout(() => {
console.log('setTimeout 2');
}, 1000);
});
console.log(2);
setTimeout(function () {
console.log(1);
}, 0);
new Promise(function (resolve, reject) {
console.log(2);
resolve();
})
.then(function () {
console.log(3);
})
.then(function () {
console.log(4);
});
console.log(6);
console.log('1');
setTimeout(function () {
console.log('2');
new Promise(function (resolve) {
console.log('3');
resolve();
}).then(function () {
console.log('4');
});
});
new Promise(function (resolve) {
console.log('5');
resolve();
}).then(function () {
console.log('6');
});
setTimeout(function () {
console.log('7');
});
setTimeout(function () {
console.log('8');
new Promise(function (resolve) {
console.log('9');
resolve();
}).then(function () {
console.log('10');
});
});
new Promise(function (resolve) {
console.log('11');
resolve();
}).then(function () {
console.log('12');
});
console.log('13');
async function async1(){
console.log('a1 start')
await async2()
/*
async2().then(res=>{
console.log('a1 end');
})
*/
console.log('a1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1()
new Promise(function (resolve){
console.log('promise1')
resolve()
}).then(function(){
console.log('promise2')
})
console.log('script end')
async function async1() {
console.log('async1 start');
await async2();
/*
async2().then(res=>{
console.log('a1 end');
})
*/
console.log('async1 end');
}
async function async2() {
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
});
}
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
async1();
new Promise(function (resolve) {
console.log('promise3');
resolve();
}).then(function () {
console.log('promise4');
});
console.log('script end');
async function async1() {
console.log('async1 start');
await async2();
/*
async2().then(res=>{
setTimeout(function () {
console.log('setTimeout1');
}, 0);
})
*/
setTimeout(function () {
console.log('setTimeout1');
}, 0);
}
async function async2() {
setTimeout(function () {
console.log('setTimeout2');
}, 0);
}
console.log('script start');
setTimeout(function () {
console.log('setTimeout3');
}, 0);
async1();
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
});
console.log('script end');
var promise = new Promise(resolve=>{
console.log(1)
resolve()
})
setTimeout(()=>{
console.log(2)
})
promise.then(()=>{
console.log(3)
})
var promise2 = getPromise()
async function getPromise(){
console.log(5)
await promise
console.log(6)
}
console.log(8)
const LazyMan = function (name) {
console.log(`Hi i am ${name}`);
function _eat(food) {
console.log(`I am eating ${food}`);
}
const callbacks = [];
class F {
sleep(timeout) {
setTimeout(function () {
console.log(`等待了${timeout}秒...`);
callbacks.forEach((cb) => cb());
}, timeout);
return this;
}
eat(food) {
callbacks.push(_eat.bind(null, food));
return this;
}
}
return new F();
};
LazyMan('Tony').sleep(10).eat('lunch');