异步解析
- 什么是异步
//异步执行
let count = 1;
let timer = setTimeout(function(){
count++;
console.log('in',count);
})
console.log('out',count);
// out 1
// in 2
//为什么?
//循环执行 + 终止
let count = 1;
let timer = setInterval(function(){
count++;
console.log('in',count)
},1000)
console.log('out',count)
setTimeout(function(){
clearInterval(timer)
console.log('clear')
},5000)
//out 1
//in 2
//in 3
//in 4
//in 5
//in 6
//clear
//持续性的动作
//看不见的队列,存放着我们需要持续,等待,后台悄悄的执行的指令
1. 进程 & 线程
a. 概念 &区别
进程:CPU资源分配的最小单位
线程:CPU调度的最小单位
映射到前端 — 浏览器新开一个窗口,是进程还是线程?- 进程
发散方向:
方向一:窗口(进程)间通信 —— storage,cookie => 多种存储的区别 => 回归项目
方向二:浏览器执行原理
浏览器执行原理
GUI渲染线程
1.解析HTML,CSS => 构建DOM树 => 布局绘制
2.与JS引擎线程互斥的,当执行JS时,GUI渲染会被挂起,任务队列空闲的时候,才会执行GUI
JS引擎线程
1.处理JS,解析执行脚本
2.处理待执行的事件,安排事件队列
3.阻塞GUI线程
定时器线程
1.异步定时器的处理和执行
2.接受JS引擎分配的定时器任务,并执行
3.处理完成之后,交给事件触发线程
异步请求线程
1.异步执行网络类的操作
2.接受JS引擎分配的异步网络请求任务,并执行
3.监听回调处理完成之后,交给事件触发线程
事件触发线程:
1.接受所有来源的事件
2.把接收到的回调事件按照顺序加入到任务队列的队尾,做好排序,交给 js 引擎处理
2. EVENT-LOOP
a.执行栈
- js单线程语言
b.执行顺序题
setTimeout(()=>{
console.log('timeout') // 进入宏任务队列
},0)
new Promise((resolve)=>{
console.log('new Promise') // 同步任务
resolve()
}).then(()=>{
console.log('Promise then') // 放入微任务队列
}).then(()=>{
console.log('Promise then then') // 放入微任务队列
})
console.log('hi') // 同步执行
// new Promise
// hi
// Promise then
// Promise then then
// timeout
微任务: promise,defineProperty,Proxy
宏任务:script,setTimeout,setinterval
先执行微任务,再执行宏任务
promise
请求当前用户可访问 => 请求数据是否可以获取 => 请求当前页面的数据
回调地狱
function wait500(input){
return new Promise((resolve, reject)=>{
console.log(500, input)
setTimeout(()=>{
resolve(input + 500)
},500)
})
}
function wait1000(input){
return new Promise((resolve, reject)=>{
console.log(1000, input)
setTimeout(()=>{
resolve(input + 1000)
},1000)
})
}
const p = new Promise((resolve, reject)=>{
resolve(1)
})
p.then(wait500)
.then(wait500)
.then(wait1000)
.then(wait500)
.then(wait1000)
.then(result =>{
sonsole.log('END', result)
})
// 全部执行 - all
Promise.all([wait500, wait1000]).then(result => {
console.log('all done', result)
})
// 竞争执行 - race
Promise.race([wait500, wait1000]).then(result => {
console.log('race done', result)
})
b. Promise 原理
-
1.promise
状态:
主状态 - pending 等待 | rejected 拒绝 | fulfilled 成功
executor - new Promise 时立刻执行 | 接收 resolve reject默认态 + 状态流转:
默认状态 - pending
状态流转 - pending => rejected
pending => fulfilled返回值:
then - 接收 onFulfilled 和 onRejected | value or reason -
- 手写
const PENDING = 'PENDING'
const REJECTED = 'REJECTED'
const FULFILLED = 'FULFILLED'
class Promise {
constructor(excutor){
// 1.默认状态
this.status = PENGING
//2.维护内部成功失败的值
this.value = undefined
this.reason = undefined
//存放成功的回调
this.onResolvedCallbacks = []
this.onRejectedCcallbacks = []
//成功的回调
let resolve = value =>{
//单向流转
if(this.status = FULFILLED){
this.status = FULFILLED
this.value = value
this.onResolvedCallbacks.forEach(fn => fn())
}
}
//失败的回调
let reject = reason =>{
//单向流转
if(this.status = REJECTED){
this.status = REJECTED
this.value = reject
this.onRejectedCcallbacks.forEach(fn => fn())
}
}
// 4. 主执行
try {
executor(resolve, reject)
} catch (error){
reject(error)
}
}
then(onFulfilled, onRejected){
//边缘检测
onFulfilled=
typeof onFulfilled === 'function'
? onFulfilled
: value => value;
onRejected=
typeof onRejected === 'function'
? onRejected
: error => { throw error };
//组装内部的promise2
let promise2 = new myPromise((resolved, rejected)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try {
let x = onFulfilled(this.value)
this.resolvePromise(promise2, x, resolve, reject)
}catch (error) {
reject(error)
}
},0)
}
if(this.status === REJECTED){
onRejected(this.reason)
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
onFulfilled(this.value)
})
this.onRejectedCcallbacks.push(()=>{
onRejected(this.reason)
})
}
})
}
}
//主触发
if(this.status === FULFILLED){
onFulfilled(this.value)
}
if(this.status === REJECTED){
onRejected(this.reason)
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
onFulfilled(this.value)
})
this.onRejectedCcallbacks.push(()=>{
onRejected(this.reason)
})
}