千峰Ajax【fetch和promise】

news2024/11/26 20:43:35

promise基础

<script>
    // Promise构造函数
    var q = new Promise(function (resolve, reject) {
      //异步
      setTimeout(function () {
        // 成功
        // resolve(["111", "222", "333"]);
        // 失败
        reject("error");
      }, 2000);
    });
    // q是promise对象
    q.then(function (res) {
      //兑现承诺,执行
      console.log("success", res);
    }).catch(function (err) {
      // 拒绝承诺,执行
      console.log("fail", err);
    });
  </script>

Promise实际是充当ajax获取后台数据后执行回调的异步执行顺序的一个媒介,客观来说就是避免ajax回调地狱(反复嵌套回调),不然代码不够直观。
Promise 流程总结:
1 .把 ajax 返回成功 / 失败的回调封装成一个 Promise 对象(同时判断 resolve / reject 状态)
2 .其对象根据传来的状态 resolve 则执行.then( res => {} // 实际在Promise.prototype上 )来执行ajax一层返回成功后的二层 ajax 请求,状态为 reject 的则执行对象的.catch( err => {} // 实际在Promise.prototype上 ),以此类推,实现异步请求的顺序执行

一个 Promise 必然处于以下几种状态之一:

待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。
一个Promise对象具有then函数,then函数接受两个函数,第一个函数当 Promise 变成接受状态(fulfilled)时被调用,第二个函数当 Promise 变成拒绝状态(rejected)时被调用。
catch 接收一个函数,在Promise被reject的时候执行,除非该函数抛出错误或返回一个失败的Promise,否则返回的Promise一直是resolved。实质上catch(failureCallback) 是 then(null, failureCallback) 的缩略形式。
finally接收一个回调函数,在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定该回调函数。这避免了同样的语句需要在then()和catch()中各写一次的情况。

使用promise封装Ajax解决回调地狱问题

//promise ajax
function pajax(options) {
  return new Promise((resolve, reject) => {
    ajax({
      //展开运算符
      ...options,
      success(res) {
        resolve(res);
      },
      error(err) {
        reject(err);
      },
    });
  });
}
export { ajax, pajax };
<script>
    pajax({
      url: "http://localhost:3000/news",
      data: { author: "王维" },
    }).then((res) => {
      console.log(res[0]);
      return pajax({
        url: "http://localhost:3000/comments",
        data: { newsId: res[0].id },
      })
        .then((res) => {
          console.log("success", res);
        })
        .catch((err) => {
          console.log("error", err);
        });
    });
  </script>

fetch基础内容:

Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。

这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案,可以很容易地被其他技术使用,例如 Service Workers。Fetch 还提供了专门的逻辑空间来定义其他与 HTTP 相关的概念,例如 CORS 和 HTTP 的扩展。
fetch 规范与 jQuery.ajax() 主要有以下的不同:

当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve(如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false),仅当网络故障时或请求被阻止时,才会标记为 reject。
fetch 不会发送跨域 cookie,除非你使用了 credentials 的初始化选项。
封装的Ajax方法和fetch比较:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>封装请求方式</title>
  </head>
  <body>
    <button id="myget">GET</button>
    <button id="mypost">POST</button>
    <button id="myput">PUT</button>
    <button id="mypatch">PATCH</button>
    <button id="mydelete">DELETE</button>
  </body>
  <script>
    // 查找
    myget.onclick = function () {
      // ajax({
      //   url: "http://localhost:3000/users",
      //   data: {
      //     username: "her",
      //     password: "345",
      //   },
      //   success: function (res) {
      //     console.log("success", res);
      //   },
      //   error: function (err) {
      //     console.log("error", err);
      //   },
      // });
      // fetch默认是get方法
      // 查询操作:
      var username = "her";
      fetch(`http://localhost:3000/users?username=${username}`)
        // fetch("http://localhost:3000/users")
        .then((res) => {
          console.log(res);
          if (res.ok === true) {
            //把数据当做json格式读取出来
            return res.json();
          } else {
            //拒绝承诺
            return Promise.reject({
              status: res.status,
              statusText: res.statusText,
            });
          }

          //返回一个字符串,文本格式
          // return res.text();
        })
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log("error", err);
        });
      // fetch不支持catch方法,所以自己要写一个if语句去判断是否连接成功
    };
    // 插入
    mypost.onclick = function () {
      // ajax({
      //   url: "http://localhost:3000/users",
      //   method: "POST",
      //   data: { name: "test", value: "77" },
      //   headers: {
      //     "content-type": "application/json",
      //   },
      //   success: function (res) {
      //     console.log("success", res);
      //   },
      //   error: function (err) {
      //     console.log("error", err);
      //   },
      // });
      //使用post方法,需要传参数
      fetch("http://localhost:3000/users", {
        method: "POST",
        headers: {
          "content-type": "application/json",
        },
        //这里对象格式要转换成JSON格式才能进行前后端交互
        body: JSON.stringify({ username: "heFan", age: "22" }),
      })
        .then((res) => res.json())
        .then((res) => {
          console.log(res);
        });
    };
    //修改:put:全部覆盖
    myput.onclick = function () {
      // ajax({
      //   url: "http://localhost:3000/users/4",
      //   method: "PUT",
      //   data: { name: "window", password: "11123" },
      //   headers: {
      //     "content-type": "application/x-www-form-urlencoded",
      //   },
      //   success: function (res) {
      //     console.log("success", res);
      //   },
      //   error: function (err) {
      //     console.log("error", err);
      //   },
      // });
      fetch("http://localhost:3000/users/3", {
        method: "PUT",
        headers: {
          "content-type": "application/json",
        },
        //这里对象格式要转换成JSON格式才能进行前后端交互
        body: JSON.stringify({ username: "heFan", age: "22" }),
      })
        .then((res) => res.json())
        .then((res) => {
          console.log(res);
        });
    };
    //patch:部分覆盖(修改)
    mypatch.onclick = function () {
      // ajax({
      //   url: "http://localhost:3000/users/4",
      //   method: "PATCH",
      //   data: { name: "feifei", sex: "woman" },
      //   headers: {
      //     "content-type": "application/x-www-form-urlencoded",
      //   },
      //   success: function (res) {
      //     console.log("success", res);
      //   },
      //   error: function (err) {
      //     console.log("error", err);
      //   },
      // });
      fetch("http://localhost:3000/users/4", {
        method: "PATCH",
        headers: {
          "content-type": "application/json",
        },
        //这里对象格式要转换成JSON格式才能进行前后端交互
        body: JSON.stringify({ username: "heFan", age: "22" }),
      })
        .then((res) => res.json())
        .then((res) => {
          console.log(res);
        });
    };

    //delete:删除
    mydelete.onclick = function () {
      // ajax({
      //   url: "http://localhost:3000/users/4",
      //   method: "DELETE",
      //   headers: {
      //     "content-type": "application/x-www-form-urlencoded",
      //   },
      //   success: function (res) {
      //     console.log("success", res);
      //   },
      //   error: function (err) {
      //     console.log("error", err);
      //   },
      // });
      fetch("http://localhost:3000/users/1", {
        method: "DELETE",
        headers: {
          "content-type": "application/json",
        },
        //这里对象格式要转换成JSON格式才能进行前后端交互
        body: JSON.stringify({ username: "heFan", age: "22" }),
      })
        .then((res) => res.json())
        .then((res) => {
          console.log(res);
        });
    };
  </script>
</html>

console.log(res);
输出结果:
在这里插入图片描述
因为fetch函数,不会判断错误,走catch那条路,就算URL写错,也会执行成功的then:

.then((res) => {
          console.log("success", res);
        })
        .catch((err) => {
          console.log("error", err);
        });

结果:success undefined
所以,要自己写一个判断条件,来确认是否连接成功:

 if (res.ok === true) {
            //把数据当做json格式读取出来
            return res.json();
          } else {
            //拒绝承诺
            return Promise.reject({
              status: res.status,
              statusText: res.statusText,
            });
          }

在这里插入图片描述
至于post、put、delete方法,需要写参数,以及决定数据格式:

{
        method: "POST",
        headers: {
          "content-type": "application/json",
        },
        //这里对象格式要转换成JSON格式才能进行前后端交互
        body: JSON.stringify({ username: "heFan", age: "22" }

详细内容可阅读开发文档:使用 Fetch

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/180876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用系统函数与堆栈快速定位app关键代码

string.trim 这个还是比较关键的&#xff0c;没准可以从这里得到加密方式&#xff0c;或者挖到sql注入&#xff0c;文件上传等漏洞。进一步利用可以打印堆栈来用 Java.perform(function(){function showStack(){console.log(Java.use("android.util.Log").getStack…

TCP/IP网络编程——基于 TCP 的服务端/客户端(下)

完整版文章请参考&#xff1a; TCP/IP网络编程完整版文章 文章目录第 5 章 基于 TCP 的服务端/客户端&#xff08;2&#xff09;5.1 回声客户端的完美实现5.1.1 回声服务器没有问题&#xff0c;只有回声客户端有问题&#xff1f;5.1.2 回声客户端问题的解决办法5.1.3 如果问题不…

chrome插件开发时使用import

问题描述 在进行chrome插件开发时&#xff0c;我们有时会希望把一些公共的方法包装成一个模块&#xff0c;例如发送网络请求的方法&#xff0c;然后在其他js文件中import然后调用&#xff0c;但是在实际操作时&#xff0c;遇到了这样的问题&#xff1a; 控制台报错cannot use …

Vistual Studio Code 安装与配置C/C++环境

1. 下载VScode 2. 安装cpptools工具 3. 下载MinGW 4. 配置环境变量 5. 使用简单的.cpp文件配置C环境 6. 运行 注&#xff1a;本文所有的地址配置要根据读者的实际情况来&#xff0c;不要照文章复制&#xff01;&#xff01;&#xff01; 下载VScode 下载链接&#xff1a;https…

浏览器调用本地DLL的方法

要在浏览器中调用本地DLL&#xff0c;常见的方法是使用插件。但是为了安全&#xff0c;现在有的浏览器对插件开发做了限制&#xff0c;不让插件调用外部DLL。比如说Chrome&#xff0c;为了调用外部的DLL&#xff0c;我们只能使用早期的chrome版本。 还有一种方法就是在电脑上安…

linux编辑器的使用(gcc,g++)

前言 gcc/g是一个编译器。 我们程序的翻译有四个步骤1.预处理(头文件展开&#xff0c;条件编译&#xff0c;宏替换&#xff0c;去注释)2.编译(c语言汇编语言)3.汇编(汇编->可重定位目标二进制文件&#xff0c;不可以被执行的&#xff0c;bin.obj)----只是把我们自己的代码进…

下载Windows ISO镜像的方法 (超详细 适合新手入门)

前言 &#x1f4dc;“作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴 目录 前言 一、镜像介绍 1、大概介绍 2、详细介绍 二、下载Window…

Solon 1.12.4 发布

一个更现代感的 Java "生态型"应用开发框架&#xff1a;更快、更小、更自由。不是 Spring&#xff0c;没有 Servlet&#xff0c;也无关 JavaEE&#xff1b;新兴独立的开放生态 &#xff08;已有150来个生态插件&#xff09; 。主框架仅 0.1 MB。 相对于 Spring Boot…

JVM学习总结,全面介绍运行时数据区域、各类垃圾收集器的原理使用、内存分配回收策略

参考资料&#xff1a;《深入理解Java虚拟机》第三版 文章目录一&#xff0c;运行时数据区域&#xff08;基础重中之重&#xff09;二&#xff0c;垃圾收集器与内存分配策略1&#xff09;对象已死2&#xff09;再谈引用3&#xff09;对象回收4&#xff09;内存分代收集理论&…

【HBase入门】10. HBase高可用、HBase架构、常见问题汇总

HBase高可用 考虑关于HBase集群的一个问题&#xff0c;在当前的HBase集群中&#xff0c;只有一个Master&#xff0c;一旦Master出现故障&#xff0c;将会导致HBase不再可用。所以&#xff0c;在实际的生产环境中&#xff0c;是非常有必要搭建一个高可用的HBase集群的。 HBase…

【Maven】聚合与继承

目录 1. 聚合工程 2. 聚合工程开发 3. 继承关系 4. 继承关系开发 5. 聚合与继承的区别 1. 聚合工程 什么叫聚合&#xff1f; 聚合&#xff1a;将多个模块组织成一个整体&#xff0c;同时进行项目构建的过程称为聚合 聚合工程&#xff1a;通常是一个不具有业务功能的”空…

如何使用Excel列提取合并器提取多个表格中的一列数据然后合并到一个文件

在我们日常工作中&#xff0c;你可能经常遇到有几十个或更多的Excel文件&#xff0c;每个文件中都包含了相同类型的信息例如姓名、邮箱、地址等等&#xff0c;但它们却在不同文件中不同的列。当你想进行数据汇总或合并的时候&#xff0c;把不同表中同样类型的数据合并在一起&am…

一款用于PE文件绑定免杀的工具: Shellter

简介 Shellter是一种动态二进制程序壳程序&#xff0c;它可以在现有的可执行文件中隐藏恶意软件。它使用动态链接库技术来实现恶意代码的注入&#xff0c;并且可以在不修改现有的可执行文件的情况下进行注入。这使得它非常难以检测&#xff0c;因为它不会改变文件的哈希值或数…

[数据结构基础]排序算法第二弹 -- 选择排序、堆排序和冒泡排序

目录 一. 选择排序 1.1 选择排序的实现思路 1.2 选择排序函数代码 1.3 选择排序的时间复杂度分析 二. 堆排序 2.1 堆排序的实现思路 2.2 堆排序函数代码 2.3 堆排序的时间复杂度分析 三. 冒泡排序 3.1 冒泡排序的基本思想 3.2 冒泡排序函数代码 3.3 冒泡排序的时间…

【微服务】Gateway统一网关

更多内容点击查看微服务学习专栏 一.引入 我们为什么需要网关&#xff1f; 当我们所有的服务摆在那里允许任何人发送请求访问是不是不太安全&#xff1f; 不是所有的业务都是对外公开的&#xff01; Gateway网关是我们服务的守门神&#xff0c;是所有微服务的统一入口&…

机器自动翻译古文拼音 - 十大宋词 - 桂枝香 金陵怀古 王安石

桂枝香金陵怀古 北宋王安石 登临送目&#xff0c;正故国晚秋&#xff0c;天气初肃。 千里澄江似练&#xff0c;翠峰如簇。 归帆去棹斜阳里&#xff0c;背西风&#xff0c;酒旗斜矗。 彩舟云淡&#xff0c;星河鹭起&#xff0c;画图难足。 念往昔、繁华竞逐&#xff0c;叹门外…

【Node.js实战】一文带你开发博客项目之初识Express(安装Express,处理路由,中间件机制)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

JAVA SE复习(第2章 Java基础语法)

本文笔记来自硅谷柴林燕老师的笔记 只为自己看笔记方便使用 不做他用第2章 Java基础语法2.1 注释&#xff08;annotation&#xff09;&#xff08;掌握&#xff09;注释&#xff1a;就是对代码的解释和说明。其目的是让人们能够更加轻松地了解代码。为代码添加注释&#xff0c;…

2023年web类第一期总结

&#x1f340;本人简介&#xff1a; 吉师大一最爱逃课的网安混子、 华为云享专家、阿里云专家博主、腾讯云自媒体分享计划博主、 华为MindSpore优秀开发者、迷雾安全团队核心成员&#xff0c;CSDN2022年运维与安全领域第15名 &#x1f341;本人制作小程序以及资源分享地址&am…

计算机相关专业混体制的解决方案(国企之银行与券商)

文章目录1、各大银行1.1 银行的分类1.2 信息科技部&#xff08;工作内容&#xff0c;招聘条件&#xff0c;待遇&#xff09;2、各大券商2.1 证券公司待遇2.1 证券公司要求3、其他金融3.1 保险公司3.2 其他金融国企之银行与券商的适用对象&#xff1a; 如果你技术好&#xff0c;…