javascript是单线程的非阻塞的脚本语言
js的任务队列分为同步任务和异步任务
同步任务
在主线程里执行,当浏览器第一遍过滤html文件的时候可以执行完;(在当前作用域直接执行的所有内容,包括执行的方法、new出来的对象)
异步任务
比较耗费时间与性能的,当浏览器执行到这些的时候会将其丢到异步任务队列中,不会立即执行的任务
异步任务分为宏任务(macrotask) 和 微任务(microtask),执行的优先级不同
宏任务:script, setTimeout, setInterval, setImmeditate, T/O, UI rendering
微任务:process, nextTick, promise.then(), object.observe, MutationObserver, await, async
回调函数是微任务,会被加入微任务队列,回调函数是宏任务,会被加入宏任务队列,微任务优先级高于宏任务
Event loop过程
微任务在DOM渲染前触发,宏任务在DOM渲染后触发
代码示例1
// 语句一
console.log(1);
// 语句二
setTimeout(()=>{
console.log(2);
},0);
//语句三
Promise.resolve().then(()=>{
console.log(3);
})
// 语句四
console.log(4);
//输出顺序
//1,4,3,2
代码示例2
console.log("script start");
setTimeout(function () {
console.log("setTimeout");
}, 0);
Promise.resolve()
.then(function () {
console.log("promise1");
})
.then(function () {
console.log("promise2");
});
console.log("script end");
代码示例3
new Promise(…)中的代码,也是同步代码,会立即执行。只有then之后的代码,才是异步执行的代码
console.log("script start");
setTimeout(function () {
console.log("timeout1");
}, 10);
new Promise((resolve) => {
console.log("promise1");
resolve();
setTimeout(() => console.log("timeout2"), 10);
}).then(function () {
console.log("then1");
});
console.log("script end");
代码示例4
async 和 await 是 Generator 和 Promise 的语法糖。async 函数和普通函数一样,只是表示这个函数里有异步操作的方法,并返回一个 Promise 对象
await后面的函数执行完毕时,await会产生一个微任务(Promise.then是微任务)。
// 等价
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
// Promise 写法
async function async1() {
console.log("async1 start");
Promise.resolve(async2()).then(() => console.log("async1 end"));
}
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
async1();
setTimeout(() => {
console.log("timeout");
}, 0);
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log("script end");
代码示例5
const p = Promise.resolve();
(async () => {
await p;
console.log('await end');
})();
p.then(() => {
console.log('then 1');
}).then(() => {
console.log('then 2');
});
// 'then 1' => 'then 2' => 'await end'
代码示例6
// 1. 开始执行
console.log(1) // 2. 打印 1
setTimeout(function () { // 6. 浏览器在 0ms 后,将该函数推入任务队列
console.log(2) // 7. 打印 2
Promise.resolve(1).then(function () { // 8. 将 resolve(1) 推入任务队列 9. 将 function函数推入任务队列
console.log('ok') // 10. 打印 ok
})
}) // 3.调用 setTimeout 函数,并定义其完成后执行的回调函数
setTimeout(function () { // 11. 浏览器 0ms 后,将该函数推入任务队列
console.log(3) // 12. 打印 3
}) // 4. 调用 setTimeout 函数,并定义其完成后执行的回调函数
// 5. 主线程执行栈清空,开始读取 任务队列 中的任务
// output: 1 2 ok 3
代码示例7
setTimeout(function(){
console.log('1')
});
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3')
});
var timer;
timer = setInterval(function(){
console.log('5');
clearInterval(timer);
});
new Promise(function(resolve){
resolve();
}).then(function(){
console.log('6')
});
console.log('4');
// 2,4,3,6,1,5
代码示例8
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
});
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0);
console.log('start');
// start -> Promise1 -> setTimeout1 -> Promise2 - > setTimeout2
实例
s
//js
const box = document.getElementById('box')
box.innerHTML = '我是后来插进去的内容
'
console.log("1");
setTimeout( ()=>{
console.log("2");
alert("定时器执行了")
},0 )
Promise.resolve().then(()=>{
console.log("3")
alert("Promise执行了")
})
console.log("4");