Appearance
异步&事件循环机制
调度任务
- 计算机里调度任务和分配任务的单位是进程
- 进程中包含着很多线程
- 浏览器是一个多进程模型 每个页签都是一个进程
- 主进程 =》 用户界面
- 渲染进程 =》 浏览器内核 js ui 渲染
- 处理请求 网络进程 绘图进程 GPU 渲染启程 插件独立的进程
渲染进程-线程
- js 的“主"线程是单线程的、ui 渲染和 js 共用主线程 互斥的 从上到下执行
- 事件、定时器、ajax 都是包含在进程中的
- new WebWorker webworker 工作线程和主线程不平等 (主线程能操作 dom)
- 所有的异步方法 宏任务( 宿主环境提供的异步方法都是宏任务 )
- 微任务 (语言本身提供的是微任务 promise.then、MutationObserver)
浏览器事件事件循环机制
- 1、先执行 script 脚本,将宏任务、微任务进行分类,如果是调用的浏览器 web api,(浏览器会开启一个线程,等时间到了,会自动放到宏任务队列、微任务无需等待直接放入队列中)
- 2、js 执行栈执行完毕后,会清空所有的微任务队列,在执行微任务的时候,再次产生的微任务会直接放在当前微任务队列的尾部一起执行
- 3、会尝试 dom 渲染
- 4、事件循环会不停的扫描任务队列、如果宏任务队列中有回调,会取出一个执行,每次执行一个宏任务,再次清空所有的微任务队列,不断循环
- 5、宏任务队列只会有一个,(微任务队列)每次在宏任务执行会创建一个新的微任务队
- 宏任务 macrotask(task): script 脚本/setTimout/IO/UIRende
- 微任务 microtask(jobs): promise/ajax/Object.observe
宏任务、微任务区别
- 宏任务执行是在 dom 渲染后触发
- 微任务执行是在 dom 渲染前触发
async、await原理
- 1、async、await 是 Promise 语法糖
- 2、async、await时基于Promise实现的,
async函数会对Promise 进行包装
- 3、async函数会返回一个Promise对象
- 4、await后面的代码都会被放到Promise.then 函数中
async await 和 promise 的区别
- async/await 出现的
异常是无法捕获的
,需要借助try/catch
来捕获异常 - 任何一个await后面的promise对象变为reject,那么整个
async都会被中断
js
// async会返回一个Promise对象
async function fn() {
return "hu";
}
(async function () {
const a = fn(); // a => promise
const b = await fn(); // hu
})();
js
console.log(1);
async function async() {
console.log(2);
await console.log(3);
console.log(4);
// Promise.resolve(console.log(3)).then(()=>{
// console.log(4)
// })
}
setTimeout(() => {
console.log(5);
}, 0);
const promise = new Promise((resolve, reject) => {
console.log(6);
resolve(7);
});
promise.then((res) => {
console.log(res);
});
async();
console.log(8);
// 1 6 2 3 8 7 4 5
js
console.log("main start"); // 1
setTimeout(function setTimeout0() {
console.log("T1:宏任务"); // 3
Promise.resolve().then(() => {
console.log("T2:微任务"); // 4
});
});
new Promise(function (resolve, reject) {
console.log("T3:Promise 构造"); // 2
setTimeout(function setTimeout300() {
console.log("T4:宏任务"); // 5
resolve("T6");
Promise.resolve().then(() => {
console.log("T5:微任务"); // 7
});
}, 300);
}).then((res) => {
console.log("T6:微任务"); // 6
});
// main start
// T3:Promise 构造
// T1:宏任务
// T2:微任务
// T4:宏任务
// T6:微任务
// T5:微任务
多个promise会交替执行
js
//第一个promise
Promise.resolve()
.then(() => {
console.log(1); // 1
})
.then(() => {
console.log(3); // 3
return Promise.resolve(7); // 会产生2个微任务进入队列中
})
.then((res) => {
console.log(res); // 7
});
//第二个promise
Promise.resolve()
.then(() => {
console.log(2); // 2
})
.then(() => {
console.log(4); // 4
})
.then(() => {
console.log(5); // 5
})
.then(() => {
console.log(6); // 6
})
.then(() => {
console.log(8); // 8
});
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
js
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 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");
// 宏 setTimeout
// 微 async1 end、promise2
// script start、async1 start、async2、promise1、script end、async1 end、promise2、setTimeout