对AJAX,Promise,async与await,axiox的一些理解
ajax
ajax是一种异步通信的方法,通过直接由 js 脚本向服务器发起 http 通信,然后根据服务器返回的数据,更新网页的相应部分,而不用刷新整个页面的一种方法
ajax特点
- AJAX的优点
- 可以无需刷新页面而与服务器端进行通信
- 允许你根据用户事件来更新部分页面内容
- AJAX的缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO 不友好(搜索引擎)
ajax使用
基本使用
使用 JavaScript 向服务器提出请求并处理响应而不阻塞用户核心对象XMLHttpRequest。
//1.创建对象
const xhr = new XMLHttpRequest()
//2.初始化
xhr.open("get", "https://api.apiopen.top/getJoke")
//3.发送
xhr.send()
//4.绑定事件,处理响应结果
xhr.onreadystatechange = function () {
//判断,证明进入最后一个阶段,所有的响应体都已经回来了
//0:代表初始化 1:请求类型和地址 2:发送请求 3:服务器返回部分数据 4:服务器全部返回
if (xhr.readyState === 4) {
//判断响应状态码 200-299 成功
if (xhr.status >= 200 && xhr.status < 300) {
//成功
console.log(xhr.response);
} else {
//失败
console.error(xhr.status);
}
}
}
ajax GET传参数
//1.创建对象
const xhr = new XMLHttpRequest()
//2.初始化
xhr.open("get", "https://api.apiopen.top/getJoke?a=1&b=2")
//3.发送
xhr.send()
//4.绑定事件,处理响应结果
xhr.onreadystatechange = function () {}
ajax POST传参数
//1.创建对象
const xhr = new XMLHttpRequest()
//2.初始化
xhr.open("post", "https://api.apiopen.top/getJoke")
//3.发送
xhr.send("a=1&b=2")
//4.绑定事件,处理响应结果
xhr.onreadystatechange = function () {}
Promise
Promise 是异步编程的一种解决方案
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
Promise特点
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
使用Promise对ajax进行封装
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("get", "https://api.apiopen.top/getJoke")
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
}
})
//指定回调
p.then(function (value) {
console.log(value);
}, function (reason) {
console.error(reason);
})
axios
axios是基于promise对ajax的一种封装
ES8:async、await
async和await两种语法结合可以让异步代码像同步代码一样
async函数
- async函数的返回值为promise对象
- promise对象的结果由async函数执行的返回值决定
如果返回的结果不是一个promise对象,则这个函数的返回结果就是一个成功的promise
如果抛出错误,返回的结果就是一个失败的promise
如果返回的结果是一个promise对象,这个promise对象是成功的,返回的结果就是成功的promise对象,这个promise对象是失败的,返回的结果就是失败的promise对象
await表达式
- await必须写在async函数中
- await右侧的表达式一般为promise对象
- await返回的是promise成功的值
- await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
const p = new Promise((resolve, reject) => {
resolve("失败")
})
async function main() {
try {
let result = await p;
console.log(result);
} catch (e) {
console.warn(e);
}
}
main()
为什么async和await可以让异步代码像同步代码一样
-
由于浏览器/引擎负责解释和执行JavaScript的主线程是单线程,同步执行一个耗时较大的任务会导致阻塞。
-
所以有了异步执行代码,异步执行代码可以解决阻塞问题,但会带来顺序的不确定性(多个异步过程的不确定性,比如话费充值功能中,要先获取用户手机号码所在的省市,再根据地区找到可能充值的面值,再进行展示)
-
如果这些任务彼此不相关,就不一定需要交互,如果没有相互影响的话,不确定性是完全可以接受的。
-
如果需要保证异步执行的顺序,就要用到Promise,Promise对象允许将这种回调函数的嵌套,改为链式调用。并用then保证执行顺序。Promise还能保证每次返回的都是一个新的Promise对象,所以代码一定被异步执行。
-
这种方法还是不够简明,语义化,你只能看见一堆then。于是有了async和await,把异步执行的代码写得像同步代码那样直观。async的函数中可以有一个或多个异步操作,一旦遇到await就会立即返回一个pending状态的Promise对象,暂时返回执行代码的控制权,使得函数外的代码得以继续执行,这是保证非阻塞的部分。并且多个异步请求是可以并发的(多个Job Queue、Ajax、Timer、I/O(Node))。等await后的异步请求resolve了(或reject),主线程才会继续执行async函数内后面的部分,这是保证的顺序性(而且最终函数返回的也是一个Promise对象)。我们说的把异步变同步指的是在async函数内部异步代码就像被同步执行的那样(继发执行),而不是它会阻塞主线程一直等待异步调用返回。
浙公网安备 33010602011771号