ajax,Promise 和 fetch

提示:文章为 学习过程中的记录实践笔记。有问题欢迎指正。

文章目录


前言

AJAX 不是编程语言,是一种从网页访问web服务器的技术。

可以实现不刷新页面更新网页

在页面加载后从服务器请求/获取数据

在后台向服务器发送数据

AJAX 等价于 Asynchronous JavaScript And XML.


一、实现步骤

  1. 创建 XMR XMLHttpRequest()
javascript 复制代码
 const xhr = new XMLHttpRequest();
  1. 配置请求 open(method,url,async,user,psw)

参数说明: 请求方式,请求地址,是否异步,可选的用户名,可选的密码

  • get 偏向 获取数据
  • post 提交数据
  • put 更新(全部)数据
  • delete 删除数据
  • patch 部分修改
请求方式 method 是否异步
GET,POST,PUT,DELETE 等 true(异步) false(同步)
javascript 复制代码
xhr.open('GET', 'http://localhost:5500/javascript/ajax/data.json')
  1. 发送请求 send()
javascript 复制代码
xhr.send();
  1. 接收请求 - 定义接收到(加载)请求时调用的函数

onload 当请求完成时会被调用

javascript 复制代码
xhr.onload = function(){
//处理返回值
}

onreadystatechange 当readyState属性发生变化时调用

二、完整示例

使用 onload 接收数据

使用 onreadystatechange

readyState 不同状态

0:请求未初始化

1:服务器连接已建立

2:请求已收到

3:正在处理请求

4:请求已完成且响应已就绪

javascript 复制代码
xhr.onreadystatechange = function () {
  // console.log(xhr.readyState, xhr.status)
  // 接收状态码 4:解析完成  http状态码 200~299 都是正确的  常见 200
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log('数据解析完成', xhr.responseText)
  } else if (xhr.readyState === 4 && xhr.status === 404) {
    console.log('请求地址不存在')
  }
}

模拟后端接口数据

ajax涉及到与后端接口数据的交互,方便模拟交互可以使用json-server 工具

json-server 可用于快速mock一个 REST API 服务器,让开发者能够专注于前端开发,同时轻松模拟后端 API,提高了开发效率和测试的准确性。

json-server中文文档

安装json-server

  • 全局安装
bash 复制代码
npm install -g json-server
  • 测试是否成功
bash 复制代码
json-server -v
//或者
json-server --version
  • 创建json 文件
    json文件结构
    文件中 user相当于是一个 user表,里面的字段,就是表中存储的字段
json 复制代码
{
  "user": [
    { "id": 1, "name": "Anan" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "userId": 1 }
  ]
}
  • 启动服务
    data.json 是要监听的json模拟文件路径
    --port 是指定端口号,省略则自动启动默认端口号
bash 复制代码
json-server --watch data.json --port 3000

在发送请求的时候,直接请求文件

获取到的返回值 就是整个json文件中的内容

三、封装AJAX

javascript 复制代码
//ajax.js

function ajax(option) {
  const options = {
    method: 'GET',
    url: '',
    data: '',
    success: function () { },//成功回调函数
    error: function () { },
    ...option,
  }

  const xhr = new XMLHttpRequest();
  const method = options.method.toUpperCase();
  const url = options.url;

  let data = null;
  if (option.data) {
    data = Object.keys(options.data).map(key => key = options.data[key]).join('&');
  }

  if (method === 'GET' && data) {
    url += '?' + data;
  }

  xhr.open(method, url);

  if (method === 'POST') {
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  }

  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      if (xhr.status >= 200 && xhr.status < 300) {
        const response = xhr.getResponseHeader('Content-Type').includes('json') ? JSON.parse(xhr.responseText) : xhr.responseText;
        options.success && options.success(response);
      } else {
        options.error && options.error(xhr.status);
      }
    }
  };

  xhr.send(method === 'POST' ? data : null);
}
export default ajax;

调用封装

回调地狱

当我们封装了ajax 创建了回调函数 success 和 error

如果我们有多个请求,需要在 前一个请求之后,拿到上一个成功之后的结果,或等待上步成功后执行,会涉及到多次调用

例如:下图中代码,被称为 回调地狱 涉及多层嵌套,不便于维护

四、Promise

Promise()是构造函数
该构造函数主要用于封装还没有添加 promise 支持的函数。

代表了一个异步操作的最终完成或者失败

Promise的出现 是为了解决回调地狱出现的

  • 一个 Promise 必然处于以下几种状态之一:
待定(pending) 已兑现(fulfilled) 已拒绝(rejected)
初始状态,既没有被兑现,也没有被拒绝。 操作成功 操作失败
  • promise基本用法

promise 有两个回调 resolve 和 reject,对应 then 和 catch

pro.then((res) =>{}) 接收到的是成功的回调结果。

通过在 new Promise((resovle,reject) => {})中执行逻辑

成功的时候,将结果 resolve(res)

此时 .then() 接收成功值;

若 失败 rejecte(res)

此时 **.catch()**接收失败信息

示例如下:

javascript 复制代码
const pro = new Promise((resolve, reject) => {
  // 异步执行
 setTimeout(() => {
    console.log('执行某些操作')
   // promise 的兑现值
   // resolve('执行成功');
    reject('执行失败')
 }, 2000)
})
//对应第一个回调函数参数 resolve
pro.then((res) => {
  console.log(res)//执行成功
})
//对应第二个回调函数参数 reject
pro.catch((res) => {
  console.log(res)//执行失败
})

如果需要处理多个逻辑,并且需要得到上一步的执行成功返回结果,可以通过链式.then

对失败结果,做统一处理

javascript 复制代码
doSomething()
  .then((result) => doSomethingElse(result))
  .then((newResult) => doThirdThing(newResult))
  .then((finalResult) => {
    console.log(`最终结果:${finalResult}`);
  })
  .catch(failureCallback);
  • Promise.all() 当有多个异步函数需要等待并发执行时 ,可以使用 Promise.all()
js 复制代码
const evt1 = new Promise((resolve,reject) =>{})
const evt2 = new Promise((resolve,reject) =>{})

// 等待两个事件执行结束后
Promise.all([evt1,evt2]).then(res =>{
  // 全都成功执行
}).catch(err => {
  // 执行失败
})

五、 async/await

复制代码
对于上面的 promise 虽然解决了回调地狱的问题,但如果逻辑过多,会有链式过长,也不够优雅。
所以 又有了 async/await 的方式 

对于上面封装的 ajax 可以 换种方式,封装为 异步函数

当执行成功时,兑现成功回调,失败则相反

  • 使用方式
    async 和 await 必须配套使用。
    如果 请求 使用await 请求的方法必须是 异步 asyn

如上图,此时在等待接口返回结果时,可以直接在赋值 const res = await asyncAjax() 接收返回值

Fetch

fetch 是一个封装的对象,功能以前是使用 XMLHttpRequest 实现的

  • fetch() 收到一个代表错误的 HTTP 状态码时,fetch() 返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500
  • 相反,它会将 Promise 状态标记为 resolve
    (如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false)
  • 仅当网络故障时或请求被阻止时 ,才会标记为 reject

fetch使用案例

  • fetch() 结合async/await

总结

通俗的说,就像是拨打电话,

  1. 首先要拿起电话new XMLHttpRequest()
  2. 打开通讯录拨号/查看通讯录 open(method,url)\
  3. 点击拨打 send()
  4. 等待接通 onreadystatechange || 接通后 onload
相关推荐
RadiumAg2 小时前
记一道有趣的面试题
前端·javascript
yangzhi_emo2 小时前
ES6笔记2
开发语言·前端·javascript
yanlele2 小时前
我用爬虫抓取了 25 年 5 月掘金热门面试文章
前端·javascript·面试
烛阴4 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
初遇你时动了情4 小时前
腾讯地图 vue3 使用 封装 地图组件
javascript·vue.js·腾讯地图
dssxyz4 小时前
uniapp打包微信小程序主包过大问题_uniapp 微信小程序时主包太大和vendor.js过大
javascript·微信小程序·uni-app
ohMyGod_1237 小时前
React16,17,18,19新特性更新对比
前端·javascript·react.js
@大迁世界7 小时前
第1章 React组件开发基础
前端·javascript·react.js·前端框架·ecmascript
一瓣橙子7 小时前
7.7日 实验03-Spark批处理开发(2)
开发语言·javascript·ajax
Hilaku7 小时前
从一个实战项目,看懂 `new DataTransfer()` 的三大妙用
前端·javascript·jquery