js的同步和异步&promise基础部分

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

js的同步和异步&promise基础部分

js中的动画:

  1. setTimeout

  2. requestAnimationFrame

js中的定时器

setTimeout / setInterval

  1. 返回值是数字,代表当前是第几个定时器

  2. clearTimeout之后需要将timer=null,后期可以基于它验证

#浏览器渲染页面机制

浏览器输入一个网址

  1. 每个网站都有对应的一个服务器,存储当前的项目资源。比如某个/project目录下,项目结构如下

1a7059c99b96a50cdc5b017bc5487988.png

  1. 请求-响应

http请求:tcp 3次握手、http与https的区别、dns解析

服务器返回的是资源文件的“源代码”

请求+响应=组合起来形成一个完整的http事务

http请求信息+服务器响应信息=合起来称为http报文

调试:network,这里看到所有的资源请求

  1. 浏览器渲染源代码

#这里扩展一下线程&进程的知识点

cpu

进程(process):每开一个应用程序,每打开一个页面,就是一个进程

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

1467465b0c77c3ff70da85a2fe63abfd.png

这些都是cpu做的事情,cpu帮你开一个线程,cpu帮你做什么事情

内存

就是我们能看到的内存条

#渲染原理

遇到link/iimg/script标签,浏览器都会分配一个新的线程去请求资源文件(加载),主线程继续往下渲染;

【性能优化点】减少线程的请求(浏览器在你本机有空间限制;多请求服务器压力也够受):

  1. css/js合成一个;

  2. 图片合成一个;图片延迟加载,第一次加载时不去请求图片;

经历几个过程:

主线程第一次渲染,自上而下走完的时候,外链资源并没有请求到,只是把html结构自上而下渲染了一遍;

  1. dom结构加载完成(document.ready即dom加载完成;window.onload:所有资源都加载完成),生成dom树;

  2. 渲染一个一个css,解析css,生成cssom树;

  3. 两者结合生成渲染树:有结构有样式;

  4. 回流:计算在视口内的确切位置;

  5. 重绘

  6. 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:

  1. 创建了promise实例,为pending状态

  2. 执行executor

  3. 执行异步代码

  4. 等待状态改变

原型链上的方法then & catch

then/catch

19f76f363a391778598fe4a840112234.png

错误处理

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

then链

then回调的参数一定是promise实例[[PromiseValue]]的值

.then(()=>{ }, ()=>{ }) 只要有任何一个方法执行了,状态就会变为resolved状态,只要没报错;有报错就是rejected状态;

下一个then拿到的是上一个then的返回结果;

所以判断一个promise成功还是失败:

如果是在executor函数中,可以通过resolve/reject

如果是在then回调中,只要执行没有报错就是resolve,报了错就是reject;

+或者返回的又是一个promise,又是一个成功/失败

如果当前then没有第2个回调,则会顺延;

2e92f104d9105296d8e79700b8ecdc39.png

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);
})

87e434c1dec172e798169a11e4159b02.png

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值