教程
Ajax,Promise,Fetch,Axios的区别
179

Ajax,Promise,Fetch,Axios的区别

说起他们的区别我们首先要知道,js中什么是同步执行和异步执行?

在js中,通常情况下代码都是自上而下同步执行的,在同步执行代码时,如果有一段代码执行的速度特别慢,会造成程序卡顿的后果。再者常见的就是向服务器发送请求,需要花费时间接受服务器返回的响应结果,对数据进行处理,因为网速和加载速度慢的原因,会带来不好的用户体验。从而引入异步处理,使代码无需等待,继续处理其他代码,直到其他程序处理完毕,js再继续之前的工作

早期处理的思路

js中的一部主要是通过事件和回调函数实现的,但是这种方式会存在一些问题

//为了方便演示,页面创建button元素,使用原生的dom来发送请求,后面会用到
<button>点我发送请求</button>
document.querySelector("button").addEventListener("click", function () {});

会出现的问题

1.不能通过return设置返回值,

function fn1() {
        setTimeout(() => {
          console.log(1);
          // 以异步的方式,来给函数设置返回值
            return 'hello'
        }, 0);
        console.log(2);
      }
      let result = fn1();
      console.log(result);

拿不到返回值,这时可以通过回调函数解决问题

function fn1(cb) {
        setTimeout(() => {
          console.log(1);
          // 以异步的方式,来给函数设置返回值
          cb("hello");
        }, 0);
        console.log(2);
      }
      fn1((result) => {
        console.log(result);
      });

2.当异步过于复杂时,多个函数相互依赖时,就会造成回调地狱问题,增加代码复杂度,难以维护

      function fn1(n, cb) {
        setTimeout(() => {
          return cb(n + 1);
        }, 0);
      }
      function fn2(n, cb) {
        setTimeout(() => {
          return cb(n + 2);
        }, 0);
      }
      function fn3(n, cb) {
        setTimeout(() => {
          return cb(n + 3);
        }, 0);
      }
      function fn4(n, cb) {
        setTimeout(() => {
          return cb(n + 4);
        }, 0);
      }
      fn1(10, (n) => {
        fn2(n, (n) => {
          fn3(n, (n) => {
            fn4(n, (n) => {
              console.log(n);//20
            });
          });
        });
      });

解决方法

1. Ajax

Ajax作为js中早期的发送异步请求的方式,翻译过来就是异步的JS和XML的意思,目前用的较少

document.querySelector("button").addEventListener("click", function () {
        //1. 创建核⼼对象
        var xhr = new XMLHttpRequest();
        //2.通过核⼼对象⽅法给当前的对象提供访问⽅式和URL路径
        xhr.open("get", "https://api.q6q.cc/blog");
        //3.发送当前的请求⾄指定的URL
        xhr.send();
        //4.异步回调接收返回值并处理
        xhr.onreadystatechange = function () {
          //xhr.readyState==4代表XMLHttpRequest对象读取服务器的响应结束
          //xhr.status==200响应成功
          if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.response);
            console.log(JSON.parse(xhr.response));
          }
        };
        console.log("我是一个波浪线~~~~~~~");
      });

拿到返回结果,并且不影响其他代码的正常运行

补充:readyState有五种可能的值:

  • 0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。
  • 1 (载入):已经调用open()方法,但尚未发送请求。
  • 2 (载入完成): 请求已经发送完成。
  • 3 (交互):可以接收到部分响应数据。
  • 4 (完成):已经接收到了全部数据,并且连接已经关闭。

2. Promise

为了解决一部带来的问题,js推出新对象promise,专门用来存储异步代码对象,他可以确保异步代码的执行和返回结果

Promise的回调函数可以指定两个参数
resolve :在代码正常执行时,来设置返回值的
reject(可选) :在代码执行出错时,用来设置错误信息,反正我不用,用catch更优雅

当Promise中的代码正常执行时,会通过then方法回调来返回结果,直接抛出异常非正常执行则不会执行then

const myPromise = new Promise((resolve, reject) => {
        // throw new Error("报错了");
        setTimeout(() => {
          console.log("异步函数");
          //设置返回值
          resolve("hello");
        }, 1000);
      });
      //   获取myPromise中的返回值
      myPromise
        .then((result) => console.log(result))
        .catch((e) => console.log(e));

这时解决上述回调地狱问题就可以直接链式调用

      function fn1(n) {
        return new Promise((resolve) => {
          resolve(n + 1);
        });
      }
      function fn2(n) {
        return new Promise((resolve) => {
          resolve(n + 2);
        });
      }
      function fn3(n) {
        return new Promise((resolve) => {
          resolve(n + 3);
        });
      }
      function fn4(n) {
        return new Promise((resolve) => {
          resolve(n + 4);
        });
      }
      fn1(10)
        .then((n) => fn2(n))
        .then((n) => fn3(n))
        .then((n) => fn4(n))
        .then((n) => console.log(n))//20
        .catch((e) => console.log(e));

3. Fetch

fetch是官方的发送异步请求的工具,基于promise,相较于ajax更加方便

document.querySelector("button").addEventListener("click", function () {
        fetch("https://api.q6q.cc/blog")
          .then((resp) => resp.json())
          .then((data) => console.log(data));
      });

4. Axios

非官方的发送异步请求的库,基于promise,需要自己引入,可以更好地封装,使用范围广,更方便

document.querySelector("button").addEventListener("click", function () {
        axios
          .get("https://api.q6q.cc/blog")
          .then((res) => {
            console.log(res.data);
          })
          .catch((e) => console.log(e));
      });

总结

技术原生作用
Ajax发送请求,太老
Promise专门为异步提供支持
Fetch官方库,基于Promise,可以直接用来发送请求
Axios×第三方,基于Promise,需要引入,能更好的封装

  • 上一篇
  • 下一篇
  • 添加评论
    评论(5)
    憨憨烧鱼

    搬个小板凳来学习了

    强仔
    11
    11

    一更新就是技术文章

    若志奕鑫

    仔佬越来越强了

    玫瑰a
    玫瑰a

    以前简单了解过异步,看完这篇文章后又收获不少,感谢分享

    welcome to qiangzai blog