JS-AJAX篇

59 阅读5分钟

什么是AJAX

AJAX(Asynchronous Javascript and Xml,异步Javascript和Xml)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容的技术。

为何使用AJAX

AJAX的核心是通过 JavaScript 异步发起网络请求,在后台与服务器通信,获取数据后动态更新页面,从而提升用户体验(避免页面刷新带来的卡顿)。

基础知识了解

  • 异步:单线程环境下的非阻塞机制:任务发起后不阻塞后续代码,完成后通过回调通知,通过事件循环实现宏观上的并发。
  • JSON:现代Web开发中常用的数据交换格式(轻量、易解析),而XML作为早期数据传输格式,目前仍在部分场景中使用(如配置文件、特定协议)。
  • API:应用程序编程接口(Application Programming Interface),是不同软件组件间交互的规则集,定义了调用方式和数据格式(如后端提供的接口、系统功能接口等),无需关注内部实现。个人理解为开源包装类/工具集
  • TCP/IP:定义数据如何在Web上传输
  • Http/Https:用于传输什么内容、网络请求和响应
  • DNS:域名系统。将人类易记的域名(如www.example.com)解析为计算机可识别的 IP 地址,实现域名与 IP 地址的映射,让用户无需记忆复杂的 IP 即可访问网络资源。

Promise事件

本质

一个未来value的占位符

状态

Promise初始状态为pending(未完成),异步操作结束后会转为fulfilled(成功)或rejected(失败),这两种状态统称为settled(已完成)。

实现(Old Method)

  1. 通过fetch函数实现对外部API的调用(需要注意的是fetch函数返回的是Promise事件)
  2. then消耗处于fulfilled状态的Promise事件,需注意用then处理fetch返回的Promise事件包含有传输数据本身、响应状态、响应头等,所以需要用response.json()提取传输值(同样用该方法也会返回Promise事件)
  3. 再次用then消耗新的Promise事件,利用真正的值进行存储处理
  4. 总体使用try...catch语句实现对Promise事件不同状态的处理,对于一些特殊的rejected状态的Promise事件需要单独抛出,如使用fetch时,需通过response.ok判断HTTP状态(true表示2xx),否则需手动throw错误,否则404/500等状态会被当作fulfilled处理。

Notice:

  • 为什么要使用Promise事件,是为了解决回调地狱(Callback Hell),便于理解和维护
  • 如果需要提取多个外部API,可以在方法串内返回利用fetch函数调用新的API所获取的Promise事件
  • 错误处理:对于可被catch语句捕捉的error,直接用err进行操作;对于需要单独抛出的error,需要使用throw new Error(...)

异步执行的幕后操作

image.png

包含组件:栈、Web APIS、微任务队列、宏任务队列

存放内容:

  • 栈(调用栈):仅执行同步代码,遵循“先进后出”原则;异步代码的回调需先进入任务队列,等待栈空后由事件循环推入栈执行。
  • Web APIS:异步任务加载运行场所
  • 微任务队列:存放Promise事件的回调函数,如then、catch、finally等,优先级高于宏服务队列
  • 宏任务队列:存在DOM回调函数,计时器任务等

执行顺序:同步代码——微服务队列中的回调函数——宏服务队列中的回调函数

举例一般情况(无await):

  • 栈中执行所有的同步代码,并将所有的异步任务放在Web APIS中加载
  • 所有异步任务在Web APIS加载完成后存放在根据属性分别存放在微任务队列和宏任务队列中
  • 栈中执行完所有的同步代码后,通过事件循环(Event Loop)依次将微任务队列和宏任务队列中任务调到栈中执行,直到结束

async/await的使用

在现代前端开发中,使用then去消耗Promise事件的方法已经过时,新的语法添加了async、await,提供了更好更方便的获取外部API的方法。

async:声明一个返回 Promise 的异步函数
await:让代码看起来像同步代码,将Promise事件等待到fulfilled或rejected状态后再进行执行,暂停函数但不阻塞全局

具体步骤如下:

  1. 创建一个async异步函数
  2. 使用try...catch语句块
  3. 用await去处理fetch以及res.json
  4. 正常执行处理外部API所得到的数据

Notice:

  • 如果对顺序有需求设置可以用await对异步函数继续等待
  • async、await的本质仍是事件循环

拓展

创建Promise对象

步骤:

  1. 写出异步事件
  2. 异步事件成功处于fulfilled状态时用——reslove(...)
  3. 异步事件失败处于rejected状态时用——reject(new Error(...))
  4. 往往在函数中直接return new Promise(reslove,reject){...}

应用:通过创建Promise对象的方法可实现一个计时器,来让程序对外部API的调用限时

Promise静态方法

  1. Promise.all ( [Promise1 , Promise2 , ... ] )——当数组内的所有Promise事件均为fulfilled类型时,取出所有的值,存放在同一个数组中并返回,否则直接error
  2. Promise.race ( [Promise1 , Promise2 , ... ] )——返回最先完成的Promise事件(无论是fulfilled或rejected类型)的值
  3. Promise.allSeteled ( [Promise1 , Promise2 , ... ] )——返回所有Promise事件的值(无论是fulfilled或rejected类型)
  4. Promise.any ( [Promise1 , Promise2 , ... ] )——返回第一个类型为fulfilled类型的Promise的值 Notice:
  • 上述方法都是传入一个Promise对象数组,返回一个Promise对象,其值为一个值/数组
  • 方法1常用于批量提取出Promise事件值并方便后续利用循环操作
  • 方法2常和定时器结合使用限制调用外部API的时间

最后

前端开发之路任重而道远,在未来仍有很多知识需要学习,小编也是一个初学者,让我们一起加油!如果这篇文章能帮到你的话,荣幸之至;如果有错误的话并指出来的话,小编将不胜感激。