js的同步和异步&promise基础部分
js中的动画:
-
setTimeout
-
requestAnimationFrame

js中的定时器
setTimeout / setInterval
-
返回值是数字,代表当前是第几个定时器
-
clearTimeout之后需要将timer=null,后期可以基于它验证

#浏览器渲染页面机制
浏览器输入一个网址
-
每个网站都有对应的一个服务器,存储当前的项目资源。比如某个/project目录下,项目结构如下

- 请求-响应
http请求:tcp 3次握手、http与https的区别、dns解析
服务器返回的是资源文件的“源代码”
请求+响应=组合起来形成一个完整的http事务
http请求信息+服务器响应信息=合起来称为http报文
调试:network,这里看到所有的资源请求

-
浏览器渲染源代码

#这里扩展一下线程&进程的知识点
cpu
进程(process):每开一个应用程序,每打开一个页面,就是一个进程

线程(thread):进程中的每个子任务就叫做线程


这些都是cpu做的事情,cpu帮你开一个线程,cpu帮你做什么事情
内存
就是我们能看到的内存条
#渲染原理
遇到link/iimg/script标签,浏览器都会分配一个新的线程去请求资源文件(加载),主线程继续往下渲染;
【性能优化点】减少线程的请求(浏览器在你本机有空间限制;多请求服务器压力也够受):
-
css/js合成一个;
-
图片合成一个;图片延迟加载,第一次加载时不去请求图片;
经历几个过程:
主线程第一次渲染,自上而下走完的时候,外链资源并没有请求到,只是把html结构自上而下渲染了一遍;
-
dom结构加载完成(document.ready即dom加载完成;window.onload:所有资源都加载完成),生成dom树;
-
渲染一个一个css,解析css,生成cssom树;
-
两者结合生成渲染树:有结构有样式;
-
回流:计算在视口内的确切位置;
-
重绘
-
display

js异步编程
js是单线程的

异步整个过程:
主线程空闲了就去轮询event queue,有任务就拿到主线程中执行;
执行完了空闲了又去找,形成一个循环——event loop。同步和异步核心的机制

setTimeout例子

let n = 0;
setTimeout(() => {
n++;
console.log(n);
}, 0);
console.time('loop')
for (let i = 0; i < 100000000; i++) { }
console.timeEnd('loop')
n += 2;
console.log(n);
这个例子注意一下
// for循环:166ms
当for循环执行完毕时第2个定时器的回调已经被放到了队列中

Promise
ES6中新增加的内置类,同Boolean、Number等一样。
所有的内置类都是函数数据类型,每个函数都有3种角色,函数(普通函数和类)和对象。
+作为对象自己的私有属性。.all .race .resolve .reject。比如Object.assign Object.create
+Promise.ptototype是给实例用的

所以以后学内置语法的时候,本身的方法和创建的实例所能调用的原型上的方法,和其余的细小的知识点
ajax
串行:
同步:async: false,第1个请求成功后才去发第2个请求
但是真实项目中不会这么用同步的

$.ajax({
url:'/nameInfo',
method:'GET',
data:{
name:'zhangsan',
},
success:(result)=>{
let id=result.id
}
})
回调地狱
并行
3个请求同时发送,都请求成功了再去做一件事情
理论上:
一个执行完嵌套另一个,形成层级嵌套,就是串行;
并行就是3个同时发送

创建一个变量,step,第1个成功step++,第2个成功step++ ……

基础知识
executor:执行
new Promise就会把executor立即执行,参数为resolve、reject
exe中当前要处理的异步任务

let promise=new Promise((resolve,reject)=>{
setTimeout(()=>{
if(Math.random()<0.5){
reject()
return;
}
resolve();
},1000)
})
三大状态
pending:初始状态
fulfilled:成功
new Promise:
-
创建了promise实例,为pending状态
-
执行executor
-
执行异步代码
-
等待状态改变

原型链上的方法then & catch
then/catch

错误处理
try-catch:为了不影响后面代码的执行

then链
then回调的参数一定是promise实例[[PromiseValue]]的值
.then(()=>{ }, ()=>{ }) 只要有任何一个方法执行了,状态就会变为resolved状态,只要没报错;有报错就是rejected状态;
下一个then拿到的是上一个then的返回结果;

所以判断一个promise成功还是失败:
如果是在executor函数中,可以通过resolve/reject
如果是在then回调中,只要执行没有报错就是resolve,报了错就是reject;
+或者返回的又是一个promise,又是一个成功/失败
如果当前then没有第2个回调,则会顺延;

let promise=new Promise((resolve,reject)=>{
resolve()
}).then(result=>{
console.log('then')
console.log(aaa)
},(error)=>{
console.log('then 2');
console.log(error);
}).catch(error=>{
console.log('catch')
console.log(error);
})
只要看上一个then生成的promise的状态是成功还是失败

一道 一环套一环的题目
解题:
只要当前这个promise状态为resolved,它就一定会往后找到那个成功回调,会沿着then链往后找;
而一旦成功回调被成功执行了,当前then的promise又会变为resolved状态,又会去找后面的成功回调……一环套一环,多米诺骨牌效应
new Promise((resolve,reject)=>{
resolve()
}).then().catch((x)=>{
console.log(1)
}).then(x=>{
console.log(2); // 2
}).then(x=>{
console.log(3); // 3
}).catch(x=>{
console.log(4);
}).then(x=>{
console.log(AAA);
}).catch().then(null,x=>{
console.log(5); // 5
})
应用
利用promise解决ajax的串行和并行
串行
第1个请求发送成功,执行resolve,把promise状态改为fulfilled;
如果失败这里什么都没干,一直处于pending状态,也就不会往下走了

把每个请求用promise管理
如果then中返回的是一个promise,那么当前这个promise实例的状态就决定了下一个then中的哪个方法会执行

最终代码:

并行
用Promise.all
let promise=new Promise(resolve=>{
resolve('a')
})
let promise1=new Promise(resolve=>{ resolve('b') })
let promiseAll=Promise.all([promise,promise1])
promiseAll.then(()=>console.log('promise all'))
setTimeout(()=>{
console.log('settimout');
console.log(promise);
console.log(promiseAll);
})

本文讲解了JavaScript中的异步编程模型,如setTimeout、requestAnimationFrame和定时器的使用,以及浏览器渲染页面的过程,重点介绍了Promise的基本概念、状态转换、then/catch链和在Ajax中的应用。同时涵盖了线程与进程、HTTP协议和性能优化策略。
1428

被折叠的 条评论
为什么被折叠?



