文章目录
一、JS单线程异步编程
1、进程和线程:
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。(进程是资源分配的最小单位)
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
浏览器中常用的线程:
GUI渲染线程
JS引擎线程
事件触发线程
定时触发器线程
异步HTTP请求线程
WebWorker
…
2、JS是单线程异步编程
异步编程:·同时做多件事情,当前事情没有做王可以接着做下一件事情
EventLoop
EventQueue
WebAPIS
宏任务 macrotask [ˈmækroʊ]
微任务 microtask [ˈmaɪkroʊ]
代码如下(示例):
循环操作是同步编程:如果设置了死循环,当前循环这个事情永远结束不了,后期的所有其他任务也都无法执行「避免出现死循环」
console.log(1);
while (1) {
}
console.log(2);
代码执行过程中,遇到一个异步编程的任务:
1、webApi先监听(监听过程中发现当前任务可以执行了,也不是立即去执行,而是再次把它放到EventQueue)中排队等待
2、主线程继续向下渲染
当主线程把所有的同步代码执行完,再去EventQueue中按照顺序取出对应的异步任务执行:
a:先异步微任务、
b:微任务都取完了,再取异步宏任务、
c:优先级队列机制(取出来的异步任务都是放在栈内存,交予主线程执行)
常见情景一:Promise产生的实例
new Promise产生的实例,状态是成功还是失败,由 executor执行是否报错{执行报错,则实例是失败态}、以及resolve还是reject执行决定
Promise.resolve(100):直接创建状态是成功的实例
Promise.reject(100):直接创建状态是失败的实例
[[PromiseState]]:状态 pending/fulfilled/rejected
[[PromiseResult]]:值 undefined
new Promise的时候会立即执行executor函数
console.log(1);
let p1 = new Promise(function executor(resolve, reject) {
console.log(2);
resolve(100); //立即修改实例的状态和值
// reject(0);
console.log(3);
});
console.log(4);
p1.then(function onfulfilled(value) {
console.log('成功:', value);
}, function onrejected(reason) {
console.log('失败:', reason);
});
console.log(5);
// 答案:1 2 3 4 5 成功:100
实例.then(onfulfilled,onrejected)
@1 首先观察实例的状态,如果此时已经知道实例是成功或者失败的状态
+ 创建一个异步“微任务”「放在WebAPI中去监听,监听的时候知道它的状态,所以直接把执行的哪个方法,挪至到EventQueue中排队等着」
+ 状态是成功,后期执行的是onfulfilled
+ 状态是失败,后期执行的是onrejected
@2 如果实例此时的状态还是pending
+ 把onfulfilled/onrejected先存储到指定的容器中 「放在WebAPI中监听状态的改变」
+ 当后期执行resolve/reject的时候
+ 立即修改实例的状态和值「同步」
+ 创建一个异步微任务,后面让指定容器中的方法执行 「挪至到EventQueue中排队等着」
console.log(1);
let p1 = new Promise(resolve => {
console.log(2);
setTimeout(() => {
console.log(3);
resolve(100);
console.log(4);
}, 1000);
console.log(5);
});
console.log(6);
p1.then(value => {
console.log('成功:', value);
}, reason => {
console.log('失败:', reason);
});
console.log(7);
// 答案:1 2 5 6 7 ...过1S后... 3 4 成功:100
“实例.then”会返回一个全新的promise实例「p2」,这个实例的成功失败,由p1管控的onfulfilled或者onrejected不论哪个方法执行决定
+ 方法执行是否返回新的promise实例,如果没有返回:
+ 方法执行只要不报错,则p2就是成功的,值就是函数返回值
+ 执行报错,则p2是失败的,值是报错原因
+ 如果返回的是新的promise实例「new-promise」,则new-promise的状态和值决定了p2的状态和值
let p1 = Promise.resolve(100);
let p2