基于Promise实现AJAX

用 Promise 实现 AJAX

在当今这个信息爆炸的时代,互联网就像一张无形的大网,将全世界连接在一起。作为这张大网上的一名开发者,我们常常需要从服务器拉取数据,并展示给用户。说到数据请求,就不得不提到两个名字:AjaxFetch。这两个技术就像是互联网世界的两位老朋友和新宠儿,它们各自有着独特的能力来帮助我们获取服务器上的资源。今天我们要聊的是如何利用 Promise 来实现 Ajax 请求。

传统的 Ajax 方案

让我们先回到过去,看看 Ajax 是怎么工作的。Ajax 的全称是 Asynchronous JavaScript and XML,它并不是一个单一的技术,而是指使用 XMLHttpRequest 对象的一种编程模式,允许网页在不重新加载的情况下更新部分内容。想象一下,你正在浏览一个社交媒体网站,突然想查看最新的消息。在过去,这可能意味着整个页面都要刷新;但现在有了 Ajax,只需要更新页面中的一部分,比如你的消息流,而不会影响到其他部分。

下面是一个简单的 Ajax 请求例子:

ini 复制代码
        // fetch的前辈 XMLHttpRequest
        const xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.github.com/orgs/lemoncode/members', true);
        xhr.onreadystatechange = function () {
            if (xhr.status == 200 && xhr.readyState == 4) {
                const data = JSON.parse(xhr.responseText);
                console.log(data);
            }
        }
        xhr.send();

在这个例子中,我们创建了一个 XMLHttpRequest 实例,设置了请求的方法、URL 和是否异步(这里为 true),然后通过 onreadystatechange 监听状态变化,当请求完成并且状态码为 200(即成功)时,处理返回的数据。

Fetch API 的登场

随着时代的发展,JavaScript 社区迎来了 Fetch API。Fetch 是基于 Promise 的,这意味着我们可以更容易地管理异步操作。Fetch 让代码看起来更加简洁和现代化,同时也提供了更好的错误处理机制。

来看一个 Fetch 的示例:

javascript 复制代码
        fetch('https://jsonplaceholder.typicode.com/users')
            .then(res=>res.json())
            .then(data=> {
                console.log(data)
            })
            .catch(err=>console.log(err))

在这里,我们直接调用了 fetch 方法,传入 URL。fetch 返回一个 Promise,所以我们能够使用 .then() 来处理成功的响应,以及 .catch() 来捕捉任何可能出现的错误。是不是感觉比 Ajax 简洁多了?

使用 Promise 实现 Ajax

什么是 Promise?

Promise 是一个对象,它可以代表一个异步操作的最终完成(或失败)及其结果值。简单来说,Promise 就像是你给朋友许下的承诺------要么成功地完成了某件事情,要么因为某些原因未能完成。在 JavaScript 中,这个"承诺"一旦被做出,就不能再改变;也就是说,Promise 的状态一旦确定,就不会再变回原来的状态。

  • promise专门解决异步耗时性问题,执行流程可控 其他大型语言一般是同步的,js 通过 es6 promise 解决了单线程 异步不好控制的问题 promise 让异步变同步 提供了完善解决异步任务的机制。
Promise 的三种状态
  • Pending(等待中) :这是 Promise 初始状态,在这个时候,我们还不知道异步操作的结果。
  • Fulfilled(已成功) :如果异步操作成功完成,Promise 的状态会从 pending 变为 fulfilled。这时候我们可以使用 .then() 方法来获取操作的结果。
  • Rejected(已失败) :相反,如果异步操作遇到了问题,Promise 的状态会变为 rejected。我们可以使用 .catch() 方法来处理这些错误。
创建和使用 Promise

当你创建一个新的 Promise 对象时,你需要提供一个执行器函数(executor),这个函数会立即执行,并接收两个参数:resolvereject。这两个函数是用来改变 Promise 状态的关键。

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 模拟异步操作
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve('Operation completed successfully!');
    } else {
      reject('Something went wrong.');
    }
  }, 1000);
});

在这个例子中,我们模拟了一个异步操作,经过一秒后决定是调用 resolve 还是 reject 函数。如果我们想要处理成功的响应,可以这样做:

javascript 复制代码
myPromise.then((message) => {
  console.log(message); // 'Operation completed successfully!'
});

而如果需要捕获可能发生的错误,我们可以添加一个 .catch()

javascript 复制代码
myPromise.catch((error) => {
  console.error(error); // 如果有错误发生,这里会输出错误信息
});
Promise 让异步代码更易于管理

Promise 的一大优势在于它让异步代码看起来更像是同步代码,这使得我们的程序逻辑更加清晰易懂。通过链式调用 .then().catch(),我们可以轻松地处理多个连续的异步操作,而不需要陷入所谓的"回调地狱"。

使用 Promise 实现 Ajax

接下来,我们来构建一个使用 Promise 封装的 Ajax 函数:

javascript 复制代码
   //   https://api.github.com/orgs/lemoncode/members  url -> http (status == 200 && xreadyState == 4) -> 异步耗时任务 
        //     -> 执行流程(DOM) -> promise 
        const getJson = function (url) {
            return new Promise((resolve, reject) => {
                // 微软推出,核心对象 XMLHttpRequest
                const xhr = new XMLHttpRequest 
                ? new XMLHttpRequest()
                : new ActiveXObject("Microsoft.XMLHTTP")
                //第三个参数表示是否异步
                xhr.open('GET', url, true)
                xhr.onreadystatechange = function () {
                    if (xhr.readyState !== 4) return
                    // 304 Not Modified 
                    // 第一次 查找 200 后端开销
                    // 之后 只要后端的数据没有变化,没有必要再去查找
                    // 就会返回 304 状态码 不传内容
                    // 告诉浏览器,直接使用本地数据
                    if (xhr.status === 200 || xhr.status === 304) {
                        resolve(xhr.responseText)
                    } else {
                        reject(new Error(xhr.responseText))
                    }
                }
                xhr.send()
            })
        }
        getJson('https://api.github.com/orgs/lemoncode/members')
        .then(data=>{
            console.log(JSON.parse(data))
        })
        .catch(error=>{
            console.log(error)
        })

这段代码定义了一个名为 getJson 的函数,它返回一个新的 Promise,当请求成功时调用 resolve,并将解析后的 JSON 数据作为参数传递;如果请求失败,则调用 reject 并提供错误信息。这样我们就有了一个可以像 Fetch 一样使用的 Ajax 函数!

arduino 复制代码
const xhr = new XMLHttpRequest ? new XMLHttpRequest() 
                               : new ActiveXObject("Microsoft.XMLHTTP")        

在早期的浏览器中,特别是IE浏览器,XMLHttpRequest 对象并不是标准的,因此需要使用 ActiveXObject 来创建一个类似的对象来进行AJAX请求,虽然现在不会出现这种情况,但也可能出现在面试的考点中。

总结

Promise 是 ES6 引入的一个非常重要的特性,它不仅简化了异步编程,还增强了代码的可读性和可靠性。通过理解 Promise 的工作原理以及如何正确地使用它,你可以编写出更加高效和优雅的 JavaScript 应用程序。无论是进行 API 请求还是处理复杂的用户交互,Promise 都是你不可或缺的好帮手。希望这篇文章能帮助你更好地掌握这一强大的工具!

相关推荐
匹马夕阳16 分钟前
Vue3-跨层组件通信Provide/Inject机制详解
前端·javascript·vue.js
我家媳妇儿萌哒哒2 小时前
vue Element Ui Upload 上传 点击一个按钮,选择多个文件后直接上传,使用防抖解决多次上传的问题。
前端·javascript·vue.js
前端青山2 小时前
JavaScript闭包的深度剖析与实际应用
开发语言·前端·javascript·前端框架·ecmascript
GISer_Jing4 小时前
React函数组件中与生命周期相关Hooks详解
前端·javascript·react.js
要加油哦~4 小时前
尚硅谷· vue3+ts 知识点学习整理 |14h的课程(持续更ing)
javascript·vue.js·学习
早上好啊! 树哥9 小时前
JavaScript Math(算数) 对象的用法详解
开发语言·javascript·ecmascript
screct_demo10 小时前
通俗易懂的讲一下Vue的双向绑定和React的单向绑定
前端·javascript·html
有心还是可以做到的嘛10 小时前
ref() 和 reactive() 区别
前端·javascript·vue.js
山楂树の13 小时前
xr-frame 通过shader去除视频背景色,加载透明视频
javascript·线性代数·ar·xr·图形渲染
拖孩14 小时前
💥大家好,我是拖孩🎤
前端·javascript·后端