Ajax

Ajax的概念及优势

什么是Ajax:

​ *Ajax(AsynchronousJavaScript And XML),(异步 JavaScript 和 XML),中文名:阿贾克斯。是指一种创建异步交互式网页应用的网页开发技术。

​ *Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术

​ *前端通过与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网(不使用Ajax)如果需要更新内容,必须重载整个网页页面。

为什么要使用Ajax

* 更自然、流畅的用户体验,对用户的操作即时响应

* 在不中断用户操作的情况下与Web服务器进行通信

* 更灵敏的响应用户访问,实现近似于桌面应用程序的交互效果

* 通过局部更新页面降低网络流量,提高网络的使用效率

同步与异步

同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是处于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。

异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。

例如:

同步:按照代码顺序一步一步的执行

异步:需要消耗时间等待的代码

a,定时器

b,事件体

所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务; //执行栈

异步任务指的是,不进入主线程、而进入任务队列(task queue)的任务,只有等主线程任务执行完毕, 任务队列开始通知主线程,请求执行任务,该任务才会进入主线程执行。 //任务队列

具体来说,异步运行机制如下:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个任务队列(task queue)。只要异步任务有了运行结果,就在任务队列之中放置一个事件。

(3)一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

注意:同步代码执行一定优于异步代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
console.log(1);
setTimeout(() => {
    console.log(2);
}, 0);
setTimeout(() => {
    console.log(3);
}, 0);
setTimeout(() => {
    console.log(4);
}, 0);
console.log(5);

let time = setInterval(() => {
    console.log("heihei");
}, 1000);
clearInterval(time);

XMLHttpRequest对象

* XMLHttpRequest的理解:

AJAX的核心对象是XMLHttpRequest,即AJAX的异步操作,和服务器交互主要依赖该对象

XMLHttpRequest对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的GET 请求的能力

以前浏览器负责显示和发送请求接收响应。两件事情同一时刻只能做一件,没法同时进行。这样会让用户感觉不好(友好性不好),

使用XMLHttpRequest对象,可以把浏览器解脱出来,可以让浏览器只负责显示,而完成请求的事情由XMLHttpRequest对象负责。 这样两者各负其责,效率更高,效果更好,用户体验很好,用户永远不会看到浏览器空白

Ajax的编写步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.创建xhr对象
let xhr = new XMLHttpRequest();
2.调用open方法
//xhr.open("请求方式get/post", "服务器文件地址", true);
xhr.open("get", "url", true); // url后面不可以有任何参数
3.调用send方法
xhr.send();
4.等->onreadystatechange事件
xhr.onreadystatechange = function() {
    if (xhr.status == 200 && xhr.readyState == 4) {
    5.返回的内容
    fun(xhr.responseText);
    }
}

Ajax状态码:

0:请求未初始化(创建完XMLHttpRequest对象)

1:服务器连接已建立(调用open方法之后)

2:请求已接收(调用send方法,请求已发送)

3:请求处理中(数据发送到了服务器)

4:请求已完成,且响应已就绪(请求完成,数据解析完毕,准备返回)

Ajax GET传参:

1
2
1,url+传递的参数("url?key1="+this.value1..);  //参数拼接在url地址后
2send(空); //send方法为空

Ajax POST传参:

1
2
3
4
//1,post传参必须设置请求头:将数据以form表单post的形式发送
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
2,url后面不可以有任何参数
3send(key1=value1&key2=value2...); //参数在send方法中以键值对的方式发送

promise

promise:就是解决回调地狱的问题,将函数嵌套调用的写法,改为平级写法,利用promise可以将异步操作的流程表达出来,避免了层层嵌套的回调函数

promise解决回调地狱的思路就是不在函数的参数位置传回调函数

* Promise解决的问题:回调

//如果代码可以这么实现 这样书写的代码更加容易理解

//fun1().then(fun2).then(fun3).then(fun4);

即Promise将回调模式的主从关系调换了一个位置,变成了同等的只是顺序的关系。

Promise的概念

所谓promise,简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从语法上说,promise是一个对象,从它可以获取异步操作的消息,promise提供了统一的API,各种异步操作都可以用同样的方法进行处理。

promise对象的特点

(1)对象的状态不受外界影响,promise对象代表一个异步操作,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是promise这个名字的由来“承若”;

(2)一旦状态改变就不会再变,任何时候都可以得到这个结果,promise对象的状态改变,只有两种可能:从pending变为fulfilled,从pending变为rejected。这时就称为resolved(已定型)。如果改变已经发生了,你再对promise对象添加回调函数,也会立即得到这个结果,这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise也有一些缺点:

首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。

其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

使用Promise对象时,

1、找到异步操作的代码,放在Prmoise构造函数的参数(函数)里

2、参数(函数)的第一个参数resolve是成功时调用的函数,对应then方法(函数)的第一个参数

3、参数(函数)的第二个参数reject是失败时调用的函数,对应

then方法(函数)的第二个参数

**then()**方法就是传原来的回调函数的

then(成功的回调,[失败的回调]);

then方法接收的两个回调函数

promise实际使用中,只处理异步操作(请求和响应)

f1().then(f2,f3)

promise对象必须实现then方法,可以说then是promise的核心,而且then方法必须返回一个promise对象,同一个promise对象可以注册多个then方法,并且回调的执行和他们注册的顺序一致。

promise All 和Race

all:处理多个请求,最终返回所有的响应结果,必须所有的请求都结束后,才会整体返回响应,一个请求失败,所有的请求都会失败,(所有的响应内容放置在一个数组中)

all处理多个请求,最终返回所有的响应结果

必须所有的请求都结束后,才会整体返回响应

所有的响应内容放置一个数组中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let p1 = new Promise(function(success, reject) {
     setTimeout(function() {
            success("p1的响应数据");
            reject("p1凉了");
        }, 1000);
    });
let p2 = new Promise(function(success, reject) {
        setTimeout(function() {
            success("p2的响应数据");
            reject("p2凉了");
        }, 2000);
    });
let p3 = new Promise(function(success) {
        setTimeout(function() {
            success("p3的响应数据");
        }, 3000);
    });
Promise.all([p1, p2, p3]).then(result => console.log(result));

race:谁快就先执行谁,最快的请求失败所有的请求都会失败

catch:表示异步失败后执行的数据状态变为reject

该方法相当于then方法的第二个参数,指向reject的回调函数,不过catch方法还有一个作用,就是在执行resolve回调函数时,如果出现错误,抛出异常,不会停止运行,而是进入catch方法中

finally:用于指定不管Promise对象最后的状态如何,都会执行的操作(在执行完then或catch指定的回调函数后,都会执行finally指定回调函数),finally方法的回调函数不接受任何参数,与状态无关,不依赖于promise的执行结果,本质上是then方法的特例

本地存储

localStorage:是一种没有时间限制的数据存储方式,可以将数据永久保存在客户端。

sessionStorage:指的是针对一个session的数据存储,即将数据保存在session对象中,当关闭浏览器后,这些数据就被删除。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。

cookie/localStorage/sessionStorage三者的异同

截图

localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
增改
1.
localStorage.setItem("name", "laowang");
localStorage.setItem("name", "小明") //(无为增,有为改)
sessionStorage.setItem("name", "laowang");
2.
localStorage.age = 18;
localStorage.age = 19;
3.
localStorage["gender"] = "M";

1.
console.log(localStorage.getItem("name"));
2.
console.log(localStorage.age);
3.
console.log(localStorage["gender"]);

let ls = localStorage;
ls.removeItem("name")

ls.clear(); //全部清除
1
2
3
4
5
6
7
//存储提取json字符串
localStorage.setItem("data", '{"name":"laowang","age":"88"}');
    console.log(JSON.parse(localStorage.getItem("data")));
//遍历
for (let i = 0; i < localStorage.length; i++) {
        console.log(localStorage.getItem(localStorage.key(i)));
}

getItem(key): 获取指定key所存储的value值

setItem(key,value)方法:将value存储到key指定的字段(无为增,有为改)。

key(index)方法:返回列表中对应索引的key值

length属性:返回key/value队列的长度

removeItem(key)方法:从Storage中删除一个对应的键值对。

clear()方法:移除所有的内容