对AJAX,Promise,async与await,axiox的一些理解

ajax

ajax是一种异步通信的方法,通过直接由 js 脚本向服务器发起 http 通信,然后根据服务器返回的数据,更新网页的相应部分,而不用刷新整个页面的一种方法

ajax特点

  • AJAX的优点
  1. 可以无需刷新页面而与服务器端进行通信
  2. 允许你根据用户事件来更新部分页面内容
  • AJAX的缺点
  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. 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函数

  1. async函数的返回值为promise对象
  2. promise对象的结果由async函数执行的返回值决定

如果返回的结果不是一个promise对象,则这个函数的返回结果就是一个成功的promise

如果抛出错误,返回的结果就是一个失败的promise

如果返回的结果是一个promise对象,这个promise对象是成功的,返回的结果就是成功的promise对象,这个promise对象是失败的,返回的结果就是失败的promise对象

await表达式

  1. await必须写在async函数中
  2. await右侧的表达式一般为promise对象
  3. await返回的是promise成功的值
  4. 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可以让异步代码像同步代码一样

  1. 由于浏览器/引擎负责解释和执行JavaScript的主线程是单线程,同步执行一个耗时较大的任务会导致阻塞。

  2. 所以有了异步执行代码,异步执行代码可以解决阻塞问题,但会带来顺序的不确定性(多个异步过程的不确定性,比如话费充值功能中,要先获取用户手机号码所在的省市,再根据地区找到可能充值的面值,再进行展示)

  3. 如果这些任务彼此不相关,就不一定需要交互,如果没有相互影响的话,不确定性是完全可以接受的。

  4. 如果需要保证异步执行的顺序,就要用到Promise,Promise对象允许将这种回调函数的嵌套,改为链式调用。并用then保证执行顺序。Promise还能保证每次返回的都是一个新的Promise对象,所以代码一定被异步执行。

  5. 这种方法还是不够简明,语义化,你只能看见一堆then。于是有了async和await,把异步执行的代码写得像同步代码那样直观。async的函数中可以有一个或多个异步操作,一旦遇到await就会立即返回一个pending状态的Promise对象,暂时返回执行代码的控制权,使得函数外的代码得以继续执行,这是保证非阻塞的部分。并且多个异步请求是可以并发的(多个Job Queue、Ajax、Timer、I/O(Node))。等await后的异步请求resolve了(或reject),主线程才会继续执行async函数内后面的部分,这是保证的顺序性(而且最终函数返回的也是一个Promise对象)。我们说的把异步变同步指的是在async函数内部异步代码就像被同步执行的那样(继发执行),而不是它会阻塞主线程一直等待异步调用返回。

posted @ 2021-03-25 14:51  扭不开奥利奥  阅读(522)  评论(0)    收藏  举报