什么是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)
- 通过
fetch函数实现对外部API的调用(需要注意的是fetch函数返回的是Promise事件) - 用
then消耗处于fulfilled状态的Promise事件,需注意用then处理fetch返回的Promise事件包含有传输数据本身、响应状态、响应头等,所以需要用response.json()提取传输值(同样用该方法也会返回Promise事件) - 再次用
then消耗新的Promise事件,利用真正的值进行存储处理 - 总体使用
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(...)
异步执行的幕后操作
包含组件:栈、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状态后再进行执行,暂停函数但不阻塞全局
具体步骤如下:
- 创建一个async异步函数
- 使用try...catch语句块
- 用await去处理fetch以及res.json
- 正常执行处理外部API所得到的数据
Notice:
- 如果对顺序有需求设置可以用await对异步函数继续等待
- async、await的本质仍是事件循环
拓展
创建Promise对象
步骤:
- 写出异步事件
- 异步事件成功处于fulfilled状态时用——reslove(...)
- 异步事件失败处于rejected状态时用——reject(new Error(...))
- 往往在函数中直接
return new Promise(reslove,reject){...}
应用:通过创建Promise对象的方法可实现一个计时器,来让程序对外部API的调用限时
Promise静态方法
- Promise.all ( [Promise1 , Promise2 , ... ] )——当数组内的所有Promise事件均为fulfilled类型时,取出所有的值,存放在同一个数组中并返回,否则直接error
- Promise.race ( [Promise1 , Promise2 , ... ] )——返回最先完成的Promise事件(无论是fulfilled或rejected类型)的值
- Promise.allSeteled ( [Promise1 , Promise2 , ... ] )——返回所有Promise事件的值(无论是fulfilled或rejected类型)
- Promise.any ( [Promise1 , Promise2 , ... ] )——返回第一个类型为fulfilled类型的Promise的值 Notice:
- 上述方法都是传入一个Promise对象数组,返回一个Promise对象,其值为一个值/数组
- 方法1常用于批量提取出Promise事件值并方便后续利用循环操作
- 方法2常和定时器结合使用限制调用外部API的时间
最后
前端开发之路任重而道远,在未来仍有很多知识需要学习,小编也是一个初学者,让我们一起加油!如果这篇文章能帮到你的话,荣幸之至;如果有错误的话并指出来的话,小编将不胜感激。