什么是异步
浏览器原理(五大线程)
GUI渲染线程
-
- 解析HTML|CSS 构建DOM树|CSSOM渲染树 => 布局 => 绘制
-
- 与js引擎是互斥的,执行js引擎时,GUI渲染线程挂起
JS引擎线程
-
- 处理js,解析执行脚本
-
- 分配、处理、执行待执行的脚本时,处理待执行事件以及维护事件队列
-
- 阻塞GUI渲染线程 => 为何会阻塞GUI => 本质需要
定时器的触发线程
-
- 异步定时器的处理和执行:setTimeout、setInterval
-
- 接收js引擎分配的定时器任务并执行
-
- 处理完成交由事件触发线程
事件触发线程
-
- 接收所有来源的事件
-
- 将回调的事件一次性添加到任务队列的队尾,交给js引擎执行
异步HTTP线程
-
- 执行异步请求类操作
-
- 接受js引擎异步请求
-
- 监听回调,交给事件触发线程处理
eventloop
执行栈
宏任务&微任务
宏任务(macro tast)类型
-
- script
-
- setTimeout
-
- setInterval
-
- I/O
微任务(micro tast)类型
-
- promise
-
- defineProperty
-
- Proxy
手写实现Promise
-
- promise状态 - pending | fulfilled | rejected
exacutor: new Promise时立即执行,接收两个参数 resolve, reject
-
- promise默认状态?状态是如何流转的?- 默认:pending 状态流转:pending => fulfilled | pending => rejected
内部维护成功变量value:undefined | thenable | promise
内部维护失败变量reason
-
- promise返回值?- then方法,接收onFulfilled和onRejected
如果then时,promise已经成功,执行onFulfilled,参数value
如果then时,promise已经失败,执行onRejected,参数reason
如果then中有异常, 执行onRejected
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected'
class Promise {
constructor(exacutor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onRerovededCallbacks = [];
this.onRejectdCallbacks = [];
let resolve = (value) => {
if(this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onRerovededCallbacks.forEach(fn => fn());
}
}
let resolve = (reason) => {
if(this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectdCallbacks.forEach(fn => fn());
}
}
try {
exacutor(resolve, reject);
} catch(err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
const promise2 = new Promise((resolve, reject) => {
if(this.status === FULFILLED) {
let x = onFulfilled(this.value);
resolve(x);
}
if(this.status === REJECTED) {
let x = onFulfilled(this.reason);
reject(x);
}
if(this.status === PENDING) {
this.onRerovededCallbacks.push(() => {
let x = onFulfilled(this.value);
resolve(x);
})
this.onRejectdCallbacks.push(() => {
let x = onRejected(this.reason);
reject(x);
})
}
})
return promise2;
}
static all = (promises) => {
const result = [];
let count = 0;
return new Promise((resolve, reject) => {
for(let i = 0; i < promises.length; i++) {
promises[i].then(data => {
result[i] = data;
if(++count === promises.length) {
resolve(result);
}
}, error => {
reject(error);
})
}
})
}
static race = (promises) => {
return new Promise((resolve, reject) => {
for(let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject);
}
})
}
}